first commit

This commit is contained in:
2025-04-01 11:48:31 +08:00
commit fcebd8474e
49 changed files with 2804 additions and 0 deletions

View File

@ -0,0 +1,15 @@
package com.greenorange.promotion;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.greenorange.promotion.mapper")
public class GreenOrangeApplication {
public static void main(String[] args) {
SpringApplication.run(GreenOrangeApplication.class, args);
}
}

View File

@ -0,0 +1,18 @@
package com.greenorange.promotion.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限校验
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
/**
* 必须有某个角色
*/
String mustRole() default "";
}

View File

@ -0,0 +1,75 @@
//package com.greenorange.promotion.aop;
//
//
//import com.greenorange.promotion.annotation.AuthCheck;
//import com.greenorange.promotion.common.ErrorCode;
//import com.greenorange.promotion.constant.UserConstant;
//import com.greenorange.promotion.exception.BusinessException;
//import com.greenorange.promotion.model.enums.UserRoleEnum;
//import jakarta.annotation.Resource;
//import jakarta.servlet.http.HttpServletRequest;
//import org.apache.commons.lang3.StringUtils;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.springframework.stereotype.Component;
//import org.springframework.web.context.request.RequestAttributes;
//import org.springframework.web.context.request.RequestContextHolder;
//import org.springframework.web.context.request.ServletRequestAttributes;
//
///**
// * 权限校验AOP
// */
//@Aspect
//@Component
//public class AuthInterceptor {
//
// @Resource
// private UserService userService;
//
// /**
// * 执行拦截
// */
// @Around("@annotation(authCheck)")
// public Object doInterceptor(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
// // 接口的权限
// String mustRole = authCheck.mustRole();
// RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
// HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
// //当前登录用户
// User loginUser = userService.getLoginUser(request);
// //必须有该权限才通过
// if (StringUtils.isNotBlank(mustRole)) {
// //mustUserRoleEnum是接口权限
// UserRoleEnum mustUserRoleEnum = UserRoleEnum.getEnumByValues(mustRole);
// if(mustUserRoleEnum == null) {
// throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
// }
// //用户权限
// String userRole = loginUser.getUserRole();
// //根据用户角色获取封装后的枚举类对象
// UserRoleEnum userRoleEnum = UserRoleEnum.getEnumByValues(userRole);
//
// //如果被封号,直接拒绝
// if (UserRoleEnum.BAN.equals(userRoleEnum)) {
// throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
// }
//
// //如果接口需要Boss权限则需要判断用户是否是boss管理员
// if (UserRoleEnum.BOSS.equals(mustUserRoleEnum)) {
// if (!mustRole.equals(userRole)) {
// throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
// }
// }
// //如果接口需要管理员权限则需要判断用户是否是boss或者admin管理员
// if (UserRoleEnum.ADMIN.equals(mustUserRoleEnum)) {
// if (!mustRole.equals(userRole) && !userRole.equals(UserConstant.BOSS_ROLE)) {
// throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
// }
// }
// }
// //通过权限校验,放行
// return joinPoint.proceed();
// }
//
//}

View File

@ -0,0 +1,34 @@
package com.greenorange.promotion.common;
import lombok.Data;
import java.io.Serializable;
/**
* 通用返回类
*/
@Data
@SuppressWarnings("all")
public class BaseResponse<T> implements Serializable {
private int code;
private T data;
private String message;
public BaseResponse(int code, T data ,String message) {
this.code = code;
this.data = data;
this.message = message;
}
public BaseResponse(int code , T data) {
this(code, data, "");
}
public BaseResponse(ErrorCode errorCode) {
this(errorCode.getCode(), null, errorCode.getMessage());
}
}

View File

@ -0,0 +1,30 @@
package com.greenorange.promotion.common;
import lombok.Getter;
@Getter
public enum ErrorCode {
SUCCESS(1,"ok"),
PARAMS_ERROR(40000,"请求参数错误"),
NOT_LOGIN_ERROR(40100,"未登录"),
NO_AUTH_ERROR(40101, "无权限"),
NOT_FOUND_ERROR(40400,"请求数据不存在"),
FORBIDDEN_ERROR(40300,"禁止访问"),
SYSTEM_ERROR(50000,"系统内部异常"),
OPERATION_ERROR(50001,"操作失败"),
DATABASE_ERROR(50002, "数据库内部异常"),
LOGIN_ERROR(40110,"登陆状态变更");
/**
* 状态码
*/
private final int code;
private final String message;
ErrorCode(int code,String message) {
this.code = code;
this.message = message;
}
}

View File

@ -0,0 +1,36 @@
package com.greenorange.promotion.common;
import com.greenorange.promotion.constant.CommonConstant;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* 分页请求
*/
@Data
public class PageRequest {
/**
* 当前页号
*/
@Schema(description = "当前页码", example = "1")
private long current = 1;
/**
* 页面大小
*/
@Schema(description = "每页展示的记录条数", example = "10")
private long pageSize = 10;
/**
* 排序字段
*/
@Schema(description = "排序字段", example = "id")
private String sortField;
/**
* 排序顺序(默认升序)
*/
@Schema(description = "排序顺序((升:ascend;降:descend", example = "ascend")
private String sortOrder = CommonConstant.SORT_ORDER_ASC;
}

View File

@ -0,0 +1,58 @@
package com.greenorange.promotion.common;
@SuppressWarnings("all")
public class ResultUtils {
/**
* 成功
*
* @param data 数据
* @param <T> 泛型
* @return 成功信息
*/
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<>(1, data , "ok");
}
/**
* 成功
*
* @param data 数据
* @param message 成功消息
* @return 成功
*/
public static <T> BaseResponse<T> success(T data, String message) {
return new BaseResponse<>(1, data, message);
}
/**
* 失败
*
* @param errorCode 自定义错误码
* @return 失败信息
*/
public static <T> BaseResponse<T> error(ErrorCode errorCode) {
return new BaseResponse<>(errorCode);
}
/**
* 失败
*
* @param code 错误码
* @param message 消息
* @return 失败信息
*/
public static <T> BaseResponse<T> error(int code, String message) {
return new BaseResponse(code, null, message);
}
/**
* 失败
*
* @param errorCode 自定义错误码
* @return 失败信息
*/
public static <T> BaseResponse<T> error(ErrorCode errorCode, String message) {
return new BaseResponse(errorCode.getCode(), null, message);
}
}

View File

@ -0,0 +1,33 @@
package com.greenorange.promotion.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 跨域配置
*/
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
// 携带cookie
config.setAllowCredentials(true);
// 放行哪些域名(必须用 patterns否则 * 会和 allowCredentials 冲突)
config.addAllowedOriginPattern("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
return bean;
}
}

View File

@ -0,0 +1,34 @@
package com.greenorange.promotion.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.info.License;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Knife4j 接口文档配置
* 官网地址
*/
@Configuration
public class Knife4jConfig {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("青橙接口文档")
.version("1.0")
.description("青橙接口文档")
.termsOfService("http://doc.xiaominfo.com")
.license(new License().name("Apache 2.0")
.url("http://doc.xiaominfo.com")));
}
}

View File

@ -0,0 +1,28 @@
package com.greenorange.promotion.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MyBatis Plus 配置
*/
@Configuration
public class MyBatisPlusConfig {
/**
* 拦截器配置
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

View File

@ -0,0 +1,18 @@
package com.greenorange.promotion.constant;
/**
* 通用常量
*/
public interface CommonConstant {
/**
* 升序
*/
String SORT_ORDER_ASC = "ascend";
/**
* 降序
*/
String SORT_ORDER_DESC = " descend";
}

View File

@ -0,0 +1,34 @@
package com.greenorange.promotion.constant;
/**
* 正则表达式常量
*
* @author <a href="https://xuande-hk.gitee.io">玄德</a>
*/
@SuppressWarnings("all")
public interface RegexConstant {
/**
* 手机号正则
*/
String PHONE_REGEX = "^1[3-9]\\d{9}$";
/**
* 邮箱正则
*/
String EMAIL_REGEX = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$";
/**
* 18位身份证号正则
*/
String ID_CARD_REGEX = "^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9xX]$";
/**
* 验证码正则, 6位数字或字母
*/
String VERIFY_CODE_REGEX = "^[a-zA-Z\\d]{6}$";
/**
* 密码正则。4~32位的字母、数字、下划线
*/
String PASSWORD_REGEX = "^\\w{4,32}$";
}

View File

@ -0,0 +1,40 @@
package com.greenorange.promotion.constant;
/**
* 用户常量
*/
@SuppressWarnings("all")
public interface UserConstant {
/**
* 盐值,混淆密码
*/
String SALT = "qingcheng";
/**
* 用户默认头像
*/
String USER_DEFAULT_AVATAR = "";
/**
* 默认角色
*/
String DEFAULT_ROLE = "user";
/**
* 管理员角色
*/
String ADMIN_ROLE = "admin";
/**
* Boss
*/
String BOSS_ROLE = "boss";
/**
* 被封号
*/
String BAN_ROLE = "ban";
}

View File

@ -0,0 +1,113 @@
package com.greenorange.promotion.controller.user;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.annotation.AuthCheck;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.UserConstant;
import com.greenorange.promotion.model.dto.CommonBatchRequest;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.user.UserAddRequest;
import com.greenorange.promotion.model.dto.user.UserQueryRequest;
import com.greenorange.promotion.model.dto.user.UserUpdateRequest;
import com.greenorange.promotion.model.vo.user.UserVO;
import com.greenorange.promotion.service.user.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 用户表 控制器
*/
@RestController
@RequestMapping("user")
@Slf4j
@Tag(name = "用户表管理")
public class UserController {
@Resource
private UserService userService;
/**
* web端管理员添加用户
* @param userAddRequest 用户添加请求体
* @return 是否添加成功
*/
@PostMapping("add")
@Operation(summary = "web端管理员添加用户", description = "参数用户表添加请求体权限管理员boss, admin)方法名addUser")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Long> addUser(@RequestBody UserAddRequest userAddRequest) {
return ResultUtils.success(userService.addUser(userAddRequest));
}
/**
* web端管理员更新用户表
* @param userUpdateRequest 用户更新请求体
* @return 是否更新成功
*/
@PostMapping("update")
@Operation(summary = "web端管理员更新用户", description = "参数用户更新请求体权限管理员boss, admin)方法名updateUser")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest) {
return ResultUtils.success(userService.updateUser(userUpdateRequest));
}
/**
* web端管理员删除用户
* @param commonRequest 用户删除请求体
* @return 是否删除成功
*/
@PostMapping("delete")
@Operation(summary = "web端管理员删除用户", description = "参数用户删除请求体权限管理员boss, admin)方法名deleteUser")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> deleteUser(@RequestBody CommonRequest commonRequest) {
return ResultUtils.success(userService.deleteUser(commonRequest));
}
/**
* Web端管理员分页查看用户表
* @param userQueryRequest 用户表查询请求体
* @return 用户表列表
*/
@PostMapping("page")
@Operation(summary = "Web端管理员分页查看用户表", description = "参数用户表查询请求体权限管理员boss, admin),方法名:listUserByPage")
public BaseResponse<Page<UserVO>> listUserByPage(@RequestBody UserQueryRequest userQueryRequest) {
return ResultUtils.success(userService.listUserByPage(userQueryRequest));
}
/**
* web端管理员根据id查询用户表
* @param commonRequest 用户表查询请求体
* @return 用户表信息
*/
@PostMapping("queryById")
@Operation(summary = "web端管理员根据id查询用户表", description = "参数用户表查询请求体权限管理员boss, admin),方法名:queryUserById")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<UserVO> queryUserById(@RequestBody CommonRequest commonRequest) {
return ResultUtils.success(userService.queryUserById(commonRequest));
}
/**
* web端管理员批量删除用户
* @param commonBatchRequest id列表
* @return 是否删除成功
*/
@PostMapping("delBatch")
@Operation(summary = "web端管理员批量删除用户", description = "参数id列表权限管理员boss, admin),方法名:delBatchUser")
@AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
public BaseResponse<Boolean> delBatchUser(@RequestBody CommonBatchRequest commonBatchRequest) {
return ResultUtils.success(userService.delBatchUser(commonBatchRequest));
}
}

View File

@ -0,0 +1,36 @@
package com.greenorange.promotion.exception;
import com.greenorange.promotion.common.ErrorCode;
/**
* 自定义异常类
*/
@SuppressWarnings("all")
public class BusinessException extends RuntimeException {
/**
* 错误码
*/
private final int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
}
public BusinessException(ErrorCode errorCode, String message) {
super(message);
this.code = errorCode.getCode();
}
public int getCode() {
return code;
}
}

View File

@ -0,0 +1,50 @@
package com.greenorange.promotion.exception;
import com.greenorange.promotion.common.BaseResponse;
import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.common.ResultUtils;
import io.swagger.v3.oas.annotations.Hidden;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理器
*/
@Slf4j
@Hidden
@RestControllerAdvice
public class GlobalExceptionHandler {
// 处理参数绑定失败的异常
@ExceptionHandler(MethodArgumentNotValidException.class)
public BaseResponse<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.error("MethodArgumentNotValidException", e);
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "参数验证失败");
}
// 处理消息体解析失败的异常
@ExceptionHandler(HttpMessageNotReadableException.class)
public BaseResponse<?> handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
log.error("HttpMessageNotReadableException", e);
return ResultUtils.error(ErrorCode.PARAMS_ERROR, "请求参数不正确");
}
@ExceptionHandler(BusinessException.class)
public BaseResponse<?> businessExceptionHandler(BusinessException e) {
log.error("BusinessException", e);
return ResultUtils.error(e.getCode(), e.getMessage());
}
@ExceptionHandler(RuntimeException.class)
public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {
log.error("RuntimeException", e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误");
}
}

View File

@ -0,0 +1,44 @@
package com.greenorange.promotion.exception;
import com.greenorange.promotion.common.ErrorCode;
/**
* 抛异常工具类
*/
@SuppressWarnings("all")
public class ThrowUtils {
/**
* 条件成立则抛异常
*
* @param condition 条件
* @param runtimeException 运行时异常
*/
public static void throwIf(boolean condition, RuntimeException runtimeException) {
if (condition) {
throw runtimeException;
}
}
/**
* 条件成立则抛异常
*
* @param condition 条件
* @param errorCode 自定义异常
*/
public static void throwIf(boolean condition, ErrorCode errorCode) {
throwIf(condition, new BusinessException(errorCode));
}
/**
* 条件成立则抛异常
*
* @param condition 条件
* @param errorCode 自定义异常
* @param message 报错信息
*/
public static void throwIf(boolean condition, ErrorCode errorCode, String message) {
throwIf(condition, new BusinessException(errorCode, message));
}
}

View File

@ -0,0 +1,119 @@
package com.greenorange.promotion.generator;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import java.util.*;
/**
* @author chenxinzhi
* @date 2025/3/30
**/
public class Generator {
// 数据源配置
private static final String DATASOURCE_URL = "jdbc:mysql://8.130.119.119:3306/qingcheng?serverTimezone=Asia/Shanghai";
private static final String USERNAME = "qingcheng";
private static final String PASSWORD = "qingcheng";
// 输出路径
private static final String OUTPUT_PATH = System.getProperty("user.dir");
// 根路径
private static final String ROOT_PATH = "/src/main/java";
// 父包名
private static final String PARENT_PATH = "com.greenorange.promotion";
// 子包名
private static final String CONTROLLER_PACKAGE = "controller.user";
private static final String DTO_PACKAGE = "model.dto.user";
private static final String VO_PACKAGE = "model.vo.user";
// 生成的文件后缀名
private static final String DTO_ADD_REQUEST = "AddRequest.java";
private static final String DTO_UPDATE_REQUEST = "UpdateRequest.java";
private static final String DTO_QUERY_REQUEST = "QueryRequest.java";
private static final String VO = "VO.java";
// 模版文件路径
private static final String CONTROLLER_TEMPLATE = "/templates/controller.java";
private static final String DTO_ADD_REQUEST_TEMPLATE = "/templates/dto/AddRequest.java.vm";
private static final String DTO_UPDATE_REQUEST_TEMPLATE = "/templates/dto/UpdateRequest.java.vm";
private static final String DTO_QUERY_REQUEST_TEMPLATE = "/templates/dto/QueryRequest.java.vm";
private static final String VO_TEMPLATE = "/templates/vo/VO.java.vm";
// 作者
private static final String AUTHOR = "chenxinzhi";
// 表注释
private static final String TABLE_COMMENT = "用户表";
// 实体类名
private static final String ENTITY_NAME = "User";
// 表名
private static final String TABLE_NAME = "user";
public static void main(String[] args) {
//1、配置数据源
FastAutoGenerator.create(DATASOURCE_URL, USERNAME, PASSWORD)
//2、全局配置
.globalConfig(builder -> {
builder.disableOpenDir() // 禁止打开输出目录 默认 true
.outputDir(OUTPUT_PATH + ROOT_PATH) // 设置输出路径:项目的 java 目录下
.author(AUTHOR) // 设置作者名
.dateType(DateType.TIME_PACK) // 定义生成的实体类中日期的类型 TIME_PACK=LocalDateTime;ONLY_DATE=Date;
.commentDate("yyyy/MM/dd"); // 注释日期 默认值 yyyy-MM-dd
})
//3、包配置
.packageConfig(builder -> {
builder.parent(PARENT_PATH) // 父包名 默认值 com.baomidou
.controller(CONTROLLER_PACKAGE); // Controller 包名 默认值 controller
})
//4、模版配置
// .templateConfig(builder -> builder
// .controller(CONTROLLER_TEMPLATE))
//5、策略配置
.strategyConfig(builder -> {
builder.addInclude(TABLE_NAME) // 设置需要生成的数据表名
.controllerBuilder()
.enableFileOverride() // 覆盖controller
.enableRestStyle() // 开启生成 @RestController 控制器
.formatFileName("%sController"); // 格式化 Controller 类文件名称,%s进行匹配表名如 UserController
builder.entityBuilder().disable(); // 禁止生成 Entity
builder.serviceBuilder().disable(); // 禁止生成 Service
builder.mapperBuilder().disable(); // 禁止生成 Mapper
})
//6、自定义配置
.injectionConfig(consumer -> {
Map<String, Object> customMap = new HashMap<>();
customMap.put("entityName", ENTITY_NAME); // 示例值
customMap.put("entityComment", TABLE_COMMENT); // 示例值
customMap.put("parentPackage", PARENT_PATH);
customMap.put("controllerPackage", CONTROLLER_PACKAGE);
customMap.put("dtoPackage", DTO_PACKAGE);
customMap.put("voPackage", VO_PACKAGE);
consumer.customMap(customMap);
// DTO
List<CustomFile> customFiles = new ArrayList<>();
customFiles.add(new CustomFile.Builder().packageName(DTO_PACKAGE).fileName(DTO_ADD_REQUEST)
.templatePath(DTO_ADD_REQUEST_TEMPLATE).enableFileOverride().build());
customFiles.add(new CustomFile.Builder().packageName(DTO_PACKAGE).fileName(DTO_UPDATE_REQUEST)
.templatePath(DTO_UPDATE_REQUEST_TEMPLATE).enableFileOverride().build());
customFiles.add(new CustomFile.Builder().packageName(DTO_PACKAGE).fileName(DTO_QUERY_REQUEST)
.templatePath(DTO_QUERY_REQUEST_TEMPLATE).enableFileOverride().build());
customFiles.add(new CustomFile.Builder().packageName(VO_PACKAGE).fileName(VO)
.templatePath(VO_TEMPLATE).enableFileOverride().build());
consumer.customFile(customFiles);
})
//7、模板
.templateEngine(new VelocityTemplateEngine())
//8、执行
.execute();
}
}

View File

@ -0,0 +1,18 @@
package com.greenorange.promotion.mapper;
import com.greenorange.promotion.model.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @author 35880
* @description 针对表【user(用户表)】的数据库操作Mapper
* @createDate 2025-03-30 23:03:14
* @Entity com.greenorange.promotion.model.entity.User
*/
public interface UserMapper extends BaseMapper<User> {
}

View File

@ -0,0 +1,21 @@
package com.greenorange.promotion.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.List;
@Data
@Schema(description = "参数:id列表", requiredProperties = {"ids"})
public class CommonBatchRequest implements Serializable {
@Schema(description = "id列表", example = "[8, 9, 17]")
private List<Long> ids;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,21 @@
package com.greenorange.promotion.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
@Schema(description = "参数:id", requiredProperties = {"id"})
public class CommonRequest implements Serializable {
/**
* id
*/
@Schema(description = "id", example = "2")
private Long id;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,23 @@
package com.greenorange.promotion.model.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
@Data
@Schema(description = "参数:String", requiredProperties = {"templateString"})
public class CommonStringRequest implements Serializable {
/**
* 字符串
*/
@Schema(description = "String", example = "templateString")
private String templateString;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,62 @@
package com.greenorange.promotion.model.dto.user;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 用户表添加请求体
*/
@Data
@Schema(description = "用户表添加请求体", requiredProperties =
{"userAccount", "userPassword", "miniOpenId", "userName", "userAvatar", "points", "userRole"})
public class UserAddRequest implements Serializable {
/**
* 账号
*/
@Schema(description = "账号", example = "qingcheng")
private String userAccount;
/**
* 密码
*/
@Schema(description = "密码", example = "123456")
private String userPassword;
/**
* 小程序openId
*/
@Schema(description = "小程序openId", example = "324324")
private String miniOpenId;
/**
* 用户昵称
*/
@Schema(description = "用户昵称", example = "Jack")
private String userName;
/**
* 用户头像
*/
@Schema(description = "用户头像", example = "https://www.com")
private String userAvatar;
/**
* 积分
*/
@Schema(description = "积分", example = "1200")
private Integer points;
/**
* 用户角色
*/
@Schema(description = "用户角色", example = "user")
private String userRole;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,38 @@
package com.greenorange.promotion.model.dto.user;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import com.greenorange.promotion.common.PageRequest;
/**
* 用户表查询请求体,继承自分页请求 PageRequest
*/
@Data
@Schema(description = "用户表查询请求体", requiredProperties = {"current", "pageSize"})
public class UserQueryRequest extends PageRequest implements Serializable {
/**
* 用户id
*/
@Schema(description = "用户id", example = "1")
private Long id;
/**
* 用户昵称
*/
@Schema(description = "用户昵称", example = "Jack")
private String userName;
/**
* 用户角色
*/
@Schema(description = "用户角色", example = "user")
private String userRole;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,68 @@
package com.greenorange.promotion.model.dto.user;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 用户表更新请求体
*/
@Data
@Schema(description = "用户表更新请求体", requiredProperties =
{"id", "userAccount", "userPassword", "miniOpenId", "userName", "userAvatar", "points", "userRole"})
public class UserUpdateRequest implements Serializable {
/**
* 用户id
*/
@Schema(description = "用户id", example = "1")
private Long id;
/**
* 账号
*/
@Schema(description = "账号", example = "qingcheng")
private String userAccount;
/**
* 密码
*/
@Schema(description = "密码", example = "123456")
private String userPassword;
/**
* 小程序openId
*/
@Schema(description = "小程序openId", example = "fdsafdfasd")
private String miniOpenId;
/**
* 用户昵称
*/
@Schema(description = "用户昵称", example = "Jack")
private String userName;
/**
* 用户头像
*/
@Schema(description = "用户头像", example = "https://www.com")
private String userAvatar;
/**
* 积分
*/
@Schema(description = "积分", example = "12000")
private Integer points;
/**
* 用户角色
*/
@Schema(description = "用户角色", example = "admin")
private String userRole;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,76 @@
package com.greenorange.promotion.model.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import lombok.Data;
/**
* 用户表
* @TableName user
*/
@TableName(value ="user")
@Data
public class User implements Serializable {
/**
* id
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 账号
*/
private String userAccount;
/**
* 密码
*/
private String userPassword;
/**
* 小程序openId
*/
private String miniOpenId;
/**
* 用户昵称
*/
private String userName;
/**
* 用户头像
*/
private String userAvatar;
/**
* 积分
*/
private Integer points;
/**
* 用户角色
*/
private String userRole;
/**
* 创建时间
*/
private Date createTime;
/**
* 更新时间
*/
private Date updateTime;
/**
* 是否删除
*/
private Integer isDelete;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,52 @@
package com.greenorange.promotion.model.enums;
import lombok.Getter;
import org.springframework.util.ObjectUtils;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户角色枚举
*/
@Getter
public enum UserRoleEnum {
USER("用户", "user"),
ADMIN("管理员", "admin"),
BOSS("Boss", "boss"),
BAN("被封号", "ban");
private final String text;
private final String value;
UserRoleEnum(String text, String value) {
this.text = text;
this.value = value;
}
/**
* 获取值列表
*/
public static List<String> getValues() {
return Arrays.stream(values()).map(item -> item.value).collect(Collectors.toList());
}
/**
* 获取值列表
*/
public static UserRoleEnum getEnumByValues(String value) {
if (ObjectUtils.isEmpty(value)) {
return null;
}
for (UserRoleEnum anEnum : UserRoleEnum.values()) {
if(anEnum.value.equals(value)) {
return anEnum;
}
}
return null;
}
}

View File

@ -0,0 +1,67 @@
package com.greenorange.promotion.model.vo.user;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 用户表 视图对象
*/
@Data
@Schema(description = "用户表 视图对象")
public class UserVO implements Serializable {
/**
* 用户id
*/
@Schema(description = "用户id", example = "1")
private Long id;
/**
* 账号
*/
@Schema(description = "账号", example = "${field.example}")
private String userAccount;
/**
* 密码
*/
@Schema(description = "密码", example = "${field.example}")
private String userPassword;
/**
* 小程序openId
*/
@Schema(description = "小程序openId", example = "${field.example}")
private String miniOpenId;
/**
* 用户昵称
*/
@Schema(description = "用户昵称", example = "${field.example}")
private String userName;
/**
* 用户头像
*/
@Schema(description = "用户头像", example = "${field.example}")
private String userAvatar;
/**
* 积分
*/
@Schema(description = "积分", example = "${field.example}")
private Integer points;
/**
* 用户角色
*/
@Schema(description = "用户角色", example = "${field.example}")
private String userRole;
@Serial
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,96 @@
package com.greenorange.promotion.service.common;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public interface CommonService {
/**
* 从源集合中提取指定属性并作为查询条件查询目标集合
* @param sourceList 源集合List<T>),包含需要提取属性的元素
* @param service 执行查询的 Service
* @param getField 提取源集合中每个元素的属性值的函数
* @param targetField 目标集合中查询字段的字段名
* @param <T> 源集合元素类型
* @param <R> 目标集合中元素类型
* @return 查询结果集合
*/
<T, R> List<R> findByFieldInTargetField(List<T> sourceList, IService<R> service, Function<T, Object> getField, String targetField);
/**
* 根据指定字段名和值,使用给定的服务对象构建查询条件。
* @param <T> 实体类类型
* @param fieldName 查询字段的名称
* @param fieldValue 查询字段的值
* @param service 用于执行查询的服务层对象
*
* @return 返回构建的 QueryWrapper 对象,用于进一步查询或修改
*/
<T> QueryWrapper<T> buildQueryWrapperByField(String fieldName, Object fieldValue, IService<T> service);
/**
* 根据指定字段名和值,使用给定的服务对象查询对应的实体类列表。
* @param <T> 实体类类型
* @param fieldName 查询字段的名称
* @param fieldValue 查询字段的值
* @param service 用于执行查询的服务层对象
* @return 返回符合条件的实体类列表(`List<T>`)。如果没有符合条件的记录,返回空列表。
*/
<T> List<T> findByFieldEqTargetField(String fieldName, Object fieldValue, IService<T> service);
/**
* 根据多个字段和对应的值进行查询。
* 该方法可以动态构建查询条件并执行查询。
*
* @param fieldConditions 查询条件的字段和值使用Map存储
* @param service 执行查询操作的服务对象通常是MyBatis-Plus的 IService
* @return 返回查询结果的列表
*/
<T> List<T> findByFieldEqTargetFields(Map<String, Object> fieldConditions, IService<T> service);
/**
* 将一个类型的 List 转换为另一个类型的 List。
* @param sourceList 源列表,类型为 T
* @param targetClass 目标类型的 Class 对象
* @param <T> 源类型
* @param <R> 目标类型
* @return 转换后的目标类型列表
*/
<T, R> List<R> convertList(List<T> sourceList, Class<R> targetClass);
/**
* 复制属性并返回新的目标对象
*
* @param source 源对象
* @param targetClass 目标对象的类型
* @param <S> 源对象类型
* @param <T> 目标对象类型
* @return 目标对象
*/
<S, T> T copyProperties(S source, Class<T> targetClass);
}

View File

@ -0,0 +1,179 @@
package com.greenorange.promotion.service.common.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.greenorange.promotion.service.common.CommonService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
public class CommonServiceImpl implements CommonService {
/**
* 从源集合中提取指定属性并作为查询条件查询目标集合
* @param sourceList 源集合List<T>),包含需要提取属性的元素
* @param service 执行查询的 Service
* @param getField 提取源集合中每个元素的属性值的函数
* @param targetField 目标集合中查询字段的字段名
* @param <T> 源集合元素类型
* @param <R> 目标集合中元素类型
* @return 查询结果集合
*/
public <T, R> List<R> findByFieldInTargetField(List<T> sourceList, IService<R> service, Function<T, Object> getField, String targetField) {
// 提取源集合中每个元素的字段值
List<Object> fieldValues = sourceList.stream()
.map(getField) // 提取每个元素的字段值
.collect(Collectors.toList());
// 如果 fieldValues 为空,直接返回空集合
if (fieldValues.isEmpty()) {
return List.of(); // 返回空集合
}
// 创建查询条件
QueryWrapper<R> queryWrapper = new QueryWrapper<>();
queryWrapper.in(targetField, fieldValues); // 根据字段值进行查询
// 执行查询并返回结果
return service.list(queryWrapper);
}
/**
* 根据指定字段名和值,使用给定的服务对象构建查询条件。
* @param <T> 实体类类型
* @param fieldName 查询字段的名称
* @param fieldValue 查询字段的值
* @param service 用于执行查询的服务层对象
*
* @return 返回构建的 QueryWrapper 对象,用于进一步查询或修改
*/
@Override
public <T> QueryWrapper<T> buildQueryWrapperByField(String fieldName, Object fieldValue, IService<T> service) {
// 创建 QueryWrapper动态构建查询条件
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(fieldName, fieldValue); // 设置等值查询条件
// 返回 QueryWrapper供外部使用
return queryWrapper;
}
/**
* 根据指定字段名和值,使用给定的服务对象查询对应的实体类列表。
* @param <T> 实体类类型
* @param fieldName 查询字段的名称
* @param fieldValue 查询字段的值
* @param service 用于执行查询的服务层对象
*
* @return 返回符合条件的实体类列表(`List<T>`)。如果没有符合条件的记录,返回空列表。
*/
@Override
public <T> List<T> findByFieldEqTargetField(String fieldName, Object fieldValue, IService<T> service) {
// 创建 QueryWrapper动态构建查询条件
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(fieldName, fieldValue); // 设置等值查询条件
// 执行查询
return service.list(queryWrapper);
}
/**
* 根据多个字段和对应的值进行查询。
* 该方法根据输入的查询条件,动态构建查询,并执行数据库查询。
* @param fieldConditions 查询条件的字段和值使用Map存储
* @param service 执行查询操作的服务对象通常是MyBatis-Plus的 IService
* @return 返回查询结果的列表
*/
@Override
public <T> List<T> findByFieldEqTargetFields(Map<String, Object> fieldConditions, IService<T> service) {
// 创建 QueryWrapper动态构建查询条件
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
// 遍历传入的条件Map逐个设置查询条件
for (Map.Entry<String, Object> entry : fieldConditions.entrySet()) {
// 设置等值查询条件
queryWrapper.eq(entry.getKey(), entry.getValue());
}
// 执行查询,并返回结果
return service.list(queryWrapper);
}
/**
* 将源列表 List<T> 转换为目标类型的列表 List<R>
* @param sourceList 源列表,包含 T 类型的对象
* @param targetClass 目标类型的 Class 对象
* @param <T> 源类型
* @param <R> 目标类型
* @return 转换后的目标类型的 List
*/
@Override
public <T, R> List<R> convertList(List<T> sourceList, Class<R> targetClass) {
// 使用 Stream 流式操作来遍历源列表,并将每个元素转换为目标类型
return sourceList.stream()
.map(source -> {
try {
// 通过反射创建目标类型的实例
R target = targetClass.getDeclaredConstructor().newInstance();
// 使用 BeanUtils.copyProperties 复制属性
BeanUtils.copyProperties(source, target);
return target;
} catch (Exception e) {
// 捕获异常并抛出运行时异常
throw new RuntimeException("Error copying properties", e);
}
})
.collect(Collectors.toList()); // 将转换后的对象收集到目标类型的列表中
}
/**
* 复制属性并返回新的目标对象
*
* @param source 源对象
* @param targetClass 目标对象的类型
* @param <S> 源对象类型
* @param <T> 目标对象类型
* @return 目标对象
*/
public <S, T> T copyProperties(S source, Class<T> targetClass) {
try {
if (source == null || targetClass == null) {
return null;
}
// 创建目标对象
T target = targetClass.getDeclaredConstructor().newInstance();
// 复制属性
BeanUtils.copyProperties(source, target);
return target;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@ -0,0 +1,68 @@
package com.greenorange.promotion.service.user;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.greenorange.promotion.model.dto.CommonBatchRequest;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.user.UserAddRequest;
import com.greenorange.promotion.model.dto.user.UserQueryRequest;
import com.greenorange.promotion.model.dto.user.UserUpdateRequest;
import com.greenorange.promotion.model.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;
import com.greenorange.promotion.model.vo.user.UserVO;
import java.util.List;
/**
* @author 35880
* @description 针对表【user(用户表)】的数据库操作Service
* @createDate 2025-03-30 23:03:14
*/
public interface UserService extends IService<User> {
/**
* 获取查询条件
*/
QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest);
/**
* 分页查询用户
*/
Page<UserVO> listUserByPage(UserQueryRequest userQueryRequest);
/**
* 根据id查询用户
*/
UserVO queryUserById(CommonRequest commonRequest);
/**
* 添加用户
*/
Long addUser(UserAddRequest userAddRequest);
/**
* 更新用户
*/
boolean updateUser(UserUpdateRequest userUpdateRequest);
/**
* 删除用户
*/
boolean deleteUser(CommonRequest commonRequest);
/**
* 批量删除用户
*/
boolean delBatchUser(CommonBatchRequest commonBatchRequest);
}

View File

@ -0,0 +1,156 @@
package com.greenorange.promotion.service.user.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.greenorange.promotion.common.ErrorCode;
import com.greenorange.promotion.common.ResultUtils;
import com.greenorange.promotion.constant.CommonConstant;
import com.greenorange.promotion.exception.BusinessException;
import com.greenorange.promotion.exception.ThrowUtils;
import com.greenorange.promotion.model.dto.CommonBatchRequest;
import com.greenorange.promotion.model.dto.CommonRequest;
import com.greenorange.promotion.model.dto.user.UserAddRequest;
import com.greenorange.promotion.model.dto.user.UserQueryRequest;
import com.greenorange.promotion.model.dto.user.UserUpdateRequest;
import com.greenorange.promotion.model.entity.User;
import com.greenorange.promotion.model.vo.user.UserVO;
import com.greenorange.promotion.service.common.CommonService;
import com.greenorange.promotion.service.user.UserService;
import com.greenorange.promotion.mapper.UserMapper;
import com.greenorange.promotion.utils.SqlUtils;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author 35880
* @description 针对表【user(用户表)】的数据库操作Service实现
* @createDate 2025-03-30 23:03:14
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
@Resource
private CommonService commonService;
/**
* 获取查询条件
*/
@Override
public QueryWrapper<User> getQueryWrapper(UserQueryRequest userQueryRequest) {
Long id = userQueryRequest.getId();
String userName = userQueryRequest.getUserName();
String userRole = userQueryRequest.getUserRole();
String sortField = userQueryRequest.getSortField();
String sortOrder = userQueryRequest.getSortOrder();
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq(id != null, "id", id);
queryWrapper.like(StringUtils.isNotBlank(userName), "userName", userName);
queryWrapper.eq(StringUtils.isNotBlank(userRole), "userRole", userRole);
queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
sortField);
return queryWrapper;
}
/**
* 分页查询用户
*/
@Override
public Page<UserVO> listUserByPage(UserQueryRequest userQueryRequest) {
if (userQueryRequest == null) throw new BusinessException(ErrorCode.PARAMS_ERROR);
long current = userQueryRequest.getCurrent();
long pageSize = userQueryRequest.getPageSize();
QueryWrapper<User> queryWrapper = this.getQueryWrapper(userQueryRequest);
Page<User> page = this.page(new Page<>(current, pageSize), queryWrapper);
List<User> userList = page.getRecords();
List<UserVO> userVOList = commonService.convertList(userList, UserVO.class);
Page<UserVO> voPage = new Page<>();
voPage.setRecords(userVOList);
voPage.setPages(page.getPages());
voPage.setCurrent(page.getCurrent());
voPage.setTotal(page.getTotal());
voPage.setSize(page.getSize());
return voPage;
}
/**
* 根据id查询用户
*/
@Override
public UserVO queryUserById(CommonRequest commonRequest) {
if (commonRequest == null || commonRequest.getId() <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User user = this.getById(commonRequest.getId());
ThrowUtils.throwIf(user == null, ErrorCode.OPERATION_ERROR, "用户不存在");
return commonService.copyProperties(user, UserVO.class);
}
/**
* 添加用户
*/
@Override
public Long addUser(UserAddRequest userAddRequest) {
if (userAddRequest == null) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User user = commonService.copyProperties(userAddRequest, User.class);
boolean result = this.save(user);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "用户添加失败");
return user.getId();
}
/**
* 更新用户
*/
@Override
public boolean updateUser(UserUpdateRequest userUpdateRequest) {
if (userUpdateRequest == null || userUpdateRequest.getId() <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
User user = commonService.copyProperties(userUpdateRequest, User.class);
boolean result = this.updateById(user);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "用户更新失败");
return true;
}
/**
* 删除用户
*/
@Override
public boolean deleteUser(CommonRequest commonRequest) {
if (commonRequest == null || commonRequest.getId() <= 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
Long id = commonRequest.getId();
boolean result = this.removeById(id);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "用户删除失败");
return true;
}
/**
* 批量删除用户
*/
@Override
public boolean delBatchUser(CommonBatchRequest commonBatchRequest) {
if (commonBatchRequest == null || CollectionUtils.isEmpty(commonBatchRequest.getIds())) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
List<Long> ids = commonBatchRequest.getIds();
boolean result = this.removeByIds(ids);
ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "用户批量删除失败");
return true;
}
}

View File

@ -0,0 +1,68 @@
package com.greenorange.promotion.utils;
import org.apache.commons.lang3.StringUtils;
import static com.greenorange.promotion.constant.RegexConstant.*;
public class RegexUtils {
/**
* 是否是无效手机格式
*
* @param phone 要校验的手机号
* @return true:符合false不符合
*/
public static boolean isPhoneInvalid(String phone) {
return mismatch(phone, PHONE_REGEX);
}
/**
* 是否是无效邮箱格式
*
* @param email 要校验的邮箱
* @return true:符合false不符合
*/
public static boolean isEmailInvalid(String email) {
return mismatch(email, EMAIL_REGEX);
}
/**
* 是否是无效18位身份证格式
*
* @param idCard 要校验的身份证号码
* @return true:符合false不符合
*/
public static boolean isIdCardInvalid(String idCard) {
return mismatch(idCard, ID_CARD_REGEX);
}
/**
* 是否是无效验证码格式
*
* @param code 要校验的验证码
* @return true:符合false不符合
*/
public static boolean isCodeInvalid(String code) {
return mismatch(code, VERIFY_CODE_REGEX);
}
// 校验是否不符合正则格式
private static boolean mismatch(String str, String regex) {
if (StringUtils.isBlank(str)) {
return true;
}
return !str.matches(regex);
}
/**
* 将除了点号以外的所有特殊字符替换都为下划线
* @param input
* @return
*/
public static String encodeUrl(String input) { return input.replaceAll("[^\\w\\u4e00-\\u9fa5.]", "_"); }
}

View File

@ -0,0 +1,22 @@
package com.greenorange.promotion.utils;
import org.apache.commons.lang3.StringUtils;
/**
* SQL工具
*/
@SuppressWarnings("all")
public class SqlUtils {
/**
* 校验排序字段是否合法(防止 SQL 注入)
*
* @param sortField
* @return
*/
public static boolean validSortField(String sortField) {
if (StringUtils.isBlank(sortField)) {
return false;
}
return !StringUtils.containsAny(sortField, "=", "(", ")", " ");
}
}