bom 文件调整

This commit is contained in:
YunaiV 2020-07-17 19:59:43 +08:00
parent 26ea8dd907
commit e3f2e15c43
87 changed files with 383 additions and 1898 deletions

View File

@ -21,39 +21,47 @@
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<optional>true</optional>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-trace</artifactId>
<optional>true</optional>
</dependency>
<!-- 日志相关 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<!-- 工具相关 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@ -62,21 +70,11 @@
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<optional>true</optional>
</dependency>
<!-- hutool 工具集减少重复开发各种Util-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>

View File

@ -1,106 +0,0 @@
package cn.iocoder.common.framework.dubbo;
import cn.iocoder.common.framework.exception.ServiceException;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.filter.ExceptionFilter;
import org.apache.dubbo.rpc.service.GenericService;
import java.lang.reflect.Method;
/**
* 基于 {@link org.apache.dubbo.rpc.filter.ExceptionFilter} 实现
*
* 主要目的是一些全局性的异常能够返回因为Dubbo Consumer 能够保证一定会引入全局性的异常
*/
@Activate(group = CommonConstants.PROVIDER)
public class DubboExceptionFilter implements Filter {
private final Logger logger;
public DubboExceptionFilter() {
this(LoggerFactory.getLogger(ExceptionFilter.class));
}
public DubboExceptionFilter(Logger logger) {
this.logger = logger;
}
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
try {
return invoker.invoke(invocation);
} catch (RuntimeException e) {
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
+ ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
throw e;
}
}
@Override
public Result onResponse(Result result, Invoker<?> invoker, Invocation invocation) {
if (result.hasException() && GenericService.class != invoker.getInterface()) {
try {
Throwable exception = result.getException();
// directly throw if it's checked exception
if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
return result;
} else if (exception instanceof ServiceException) { // add by 芋艿如果是业务异常继续抛出
return result;
}
// directly throw if the exception appears in the signature
try {
Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
Class<?>[] exceptionClassses = method.getExceptionTypes();
for (Class<?> exceptionClass : exceptionClassses) {
if (exception.getClass().equals(exceptionClass)) {
return result;
}
}
} catch (NoSuchMethodException e) {
return result;
}
// for the exception not found in method's signature, print ERROR message in server's log.
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
+ ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
// directly throw if exception class and interface class are in the same jar file.
String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
return result;
}
// directly throw if it's JDK exception
String className = exception.getClass().getName();
if (className.startsWith("java.") || className.startsWith("javax.")) {
return result;
}
// directly throw if it's dubbo exception
if (exception instanceof RpcException) {
return result;
}
// otherwise, wrap with RuntimeException and throw back to the client
result.setException(new RuntimeException(StringUtils.toString(exception)));
return result;
} catch (Throwable e) {
logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()
+ ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
+ ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
return result;
}
}
return result;
}
}

View File

@ -43,4 +43,6 @@ public final class ServiceException extends RuntimeException {
return code;
}
}

View File

@ -1,52 +1,9 @@
package cn.iocoder.common.framework.util;
import cn.iocoder.common.framework.exception.ServiceException;
import org.apache.commons.lang3.exception.ExceptionUtils;
import javax.validation.ConstraintViolationException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.UndeclaredThrowableException;
public class ExceptionUtil {
public static ServiceException getServiceException(Exception e) {
if (e instanceof UndeclaredThrowableException) {
return getServiceException((UndeclaredThrowableException) e);
}
return null;
}
// 处理 Spring 动态代理调用时发生 UndeclaredThrowableException 的情况
// 不了解的胖友可以先看看 https://segmentfault.com/a/1190000012262244 文章
// 原因是
// 1. Dubbo 动态代理 Wrapper 会将抛出的异常包装成 InvocationTargetException 异常
// 2. Spring AOP 发现是 InvocationTargetException 异常是非方法定义的异常则会包装成 UndeclaredThrowableException 异常
@Deprecated // https://github.com/apache/incubator-dubbo/issues/3386 Dubbo 2.6.5 会触发该问题 2.7.1 版本已经解决
public static ServiceException getServiceException(UndeclaredThrowableException e) {
Throwable undeclaredThrowable = e.getUndeclaredThrowable();
if (undeclaredThrowable instanceof InvocationTargetException) {
InvocationTargetException invocationTargetException = (InvocationTargetException) undeclaredThrowable;
Throwable targetException = invocationTargetException.getTargetException();
if (targetException != null & targetException instanceof ServiceException) {
return (ServiceException) targetException;
}
}
return null;
}
@Deprecated // https://github.com/apache/incubator-dubbo/issues/3386 Dubbo 2.6.5 会触发该问题 2.7.1 版本已经解决
public static ConstraintViolationException getConstraintViolationException(UndeclaredThrowableException e) {
Throwable undeclaredThrowable = e.getUndeclaredThrowable();
if (undeclaredThrowable instanceof InvocationTargetException) {
InvocationTargetException invocationTargetException = (InvocationTargetException) undeclaredThrowable;
Throwable targetException = invocationTargetException.getTargetException();
if (targetException instanceof ConstraintViolationException) {
return (ConstraintViolationException) targetException;
}
}
return null;
}
public static String getMessage(Throwable th) {
return ExceptionUtils.getMessage(th);
}

View File

@ -2,7 +2,7 @@ package cn.iocoder.common.framework.vo;
import cn.iocoder.common.framework.enums.GlobalErrorCodeEnum;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.util.Assert;
import java.io.Serializable;
@ -95,12 +95,12 @@ public final class CommonResult<T> implements Serializable {
return this;
}
@JsonIgnore
@JSONField(serialize = false) // 避免序列化
public boolean isSuccess() {
return CODE_SUCCESS.equals(code);
}
@JsonIgnore
@JSONField(serialize = false) // 避免序列化
public boolean isError() {
return !isSuccess();
}

View File

@ -3,42 +3,41 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<artifactId>common</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>demo-business-api</artifactId>
<artifactId>mall-spring-boot-starter-dubbo</artifactId>
<dependencies>
<!-- Mall 相关 -->
<!-- 通用相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
<!-- RPC 相关 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- 工具类相关 -->
<!-- 日志相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<!-- 工具相关 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
</dependencies>

View File

@ -0,0 +1,116 @@
package cn.iocoder.mall.dubbo.core.filter;
import cn.iocoder.common.framework.enums.GlobalErrorCodeEnum;
import cn.iocoder.common.framework.exception.ServiceException;
import cn.iocoder.common.framework.util.ExceptionUtil;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.CommonResult;
import org.apache.dubbo.rpc.*;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.lang.reflect.Type;
public class DubboProviderExceptionFilter implements Filter, Filter.Listener {
private Logger logger = LoggerFactory.getLogger(DubboProviderExceptionFilter.class);
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
return invoker.invoke(invocation);
}
@Override
public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
try {
// 转换异常
Throwable exception = appResponse.getException();
if (exception instanceof ConstraintViolationException) {
exception = this.constraintViolationExceptionHandler((ConstraintViolationException) exception);
}
// 根据不同的方法 schema 返回结果
// 第一种情况则根据返回参数类型是否是 CommonResult 的情况则将 ServiceException 转换成 CommonResult
if (isReturnCommonResult(invocation)) {
// 清空异常
appResponse.setException(null);
// 设置结果
CommonResult exceptionResult = new CommonResult();
appResponse.setValue(exceptionResult);
// 处理非 ServiceException 业务异常转换成 ServiceException 业务异常
if (!(exception instanceof ServiceException)) {
logger.error("[onResponse][service({}) method({}) params({}) 执行异常]",
invocation.getServiceName(), invocation.getServiceName(), invocation.getArguments(), exception);
//
}
}
// 1. 处理 ServiceException 异常的情况
if (exception instanceof ServiceException) {
ServiceException serviceException = (ServiceException) exception;
// 则根据返回参数类型是否是 CommonResult 的情况则将 ServiceException 转换成 CommonResult
if (isReturnCommonResult(invocation)) {
// 通用返回
CommonResult exceptionResult = new CommonResult();
exceptionResult.setCode(serviceException.getCode());
exceptionResult.setMessage(serviceException.getMessage());
appResponse.setValue(exceptionResult);
// 清空异常
appResponse.setException(null);
// 如果不是 CommonResult 的情况则将 ServiceException 转换成 DubboInvokeException 避免可能存在的反序列化问题
} else {
RpcContext context = RpcContext.getContext();
appResponse.setException(new DubboInvokeException(exception.getMessage(), context.getLocalHost(), context.getLocalHostName()));
}
// 2. 处理非 ServiceException 异常的情况
} else {
RpcContext context = RpcContext.getContext();
appResponse.setException(new DubboInvokeException(exception.getMessage(), context.getLocalHost(), context.getLocalHostName()));
}
} catch (Throwable e) {
logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
}
}
}
@Override
public void onError(Throwable e, Invoker<?> invoker, Invocation invocation) {
logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
}
private boolean isReturnCommonResult(Invocation invocation) {
if (!(invocation instanceof RpcInvocation)) {
return false;
}
RpcInvocation rpcInvocation = (RpcInvocation) invocation;
Type[] returnTypes = rpcInvocation.getReturnTypes();
if (returnTypes.length == 0) {
return false;
}
Type returnType = returnTypes[0];
if (!(returnType instanceof Class)) {
return false;
}
Class returnClass = (Class) returnType;
return returnClass == CommonResult.class;
}
/**
* 处理 Validator 校验不通过产生的异常
*/
private ServiceException constraintViolationExceptionHandler(ConstraintViolationException ex) {
logger.warn("[constraintViolationExceptionHandler]", ex);
ConstraintViolation<?> constraintViolation = ex.getConstraintViolations().iterator().next();
return ServiceExceptionUtil.exception0(GlobalErrorCodeEnum.BAD_REQUEST.getCode(),
String.format("请求参数不正确:%s", constraintViolation.getMessage()));
}
private ServiceException defaultExceptionHandler() {
}
}

View File

@ -0,0 +1,4 @@
/**
* 占坑
*/
package cn.iocoder.mall.dubbo.core;

View File

@ -6,7 +6,9 @@ import cn.iocoder.mall.web.config.CommonWebAutoConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@ -15,10 +17,17 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@AutoConfigureAfter(CommonWebAutoConfiguration.class) // CommonWebAutoConfiguration 之后自动配置保证过滤器的顺序
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@EnableConfigurationProperties(AdminSecurityProperties.class)
public class AdminSecurityAutoConfiguration implements WebMvcConfigurer {
private Logger logger = LoggerFactory.getLogger(getClass());
@Bean
@ConditionalOnMissingBean
public AdminSecurityProperties adminSecurityProperties() {
return new AdminSecurityProperties();
}
// ========== 拦截器相关 ==========
@Bean
@ -33,11 +42,16 @@ public class AdminSecurityAutoConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
AdminSecurityProperties properties = this.adminSecurityProperties();
// AdminSecurityInterceptor 拦截器
registry.addInterceptor(this.adminSecurityInterceptor());
registry.addInterceptor(this.adminSecurityInterceptor())
.excludePathPatterns(properties.getIgnorePaths())
.excludePathPatterns(properties.getDefaultIgnorePaths());
logger.info("[addInterceptors][加载 AdminSecurityInterceptor 拦截器完成]");
// AdminDemoInterceptor 拦截器
registry.addInterceptor(this.adminDemoInterceptor());
registry.addInterceptor(this.adminDemoInterceptor())
.excludePathPatterns(properties.getIgnorePaths())
.excludePathPatterns(properties.getDefaultIgnorePaths());
logger.info("[addInterceptors][加载 AdminDemoInterceptor 拦截器完成]");
}

View File

@ -0,0 +1,41 @@
package cn.iocoder.mall.security.admin.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("mall.security.admin")
public class AdminSecurityProperties {
private static final String[] DEFAULT_IGNORE_PATHS = new String[]{
// Swagger 相关
"/doc.html", "/swagger-resources", "/swagger-resources/**",
// Actuator 相关
};
/**
* 自定义忽略 Path
*/
private String[] ignorePaths = new String[0];
/**
* 默认忽略 Path
*/
private String[] defaultIgnorePaths = DEFAULT_IGNORE_PATHS;
public String[] getIgnorePaths() {
return ignorePaths;
}
public AdminSecurityProperties setIgnorePaths(String[] ignorePaths) {
this.ignorePaths = ignorePaths;
return this;
}
public String[] getDefaultIgnorePaths() {
return defaultIgnorePaths;
}
public AdminSecurityProperties setDefaultIgnorePaths(String[] defaultIgnorePaths) {
this.defaultIgnorePaths = defaultIgnorePaths;
return this;
}
}

View File

@ -154,7 +154,7 @@ public class GlobalExceptionHandler {
* 处理系统异常兜底处理所有的一切
*/
@ExceptionHandler(value = Exception.class)
public CommonResult exceptionHandler(HttpServletRequest req, Throwable e) {
public CommonResult defaultExceptionHandler(HttpServletRequest req, Throwable e) {
logger.error("[exceptionHandler]", e);
// 插入异常日志
SystemExceptionLogCreateDTO exceptionLog = new SystemExceptionLogCreateDTO();

View File

@ -20,17 +20,8 @@
<module>mall-spring-boot-starter-security-admin</module>
<module>mall-spring-boot-starter-security-user</module>
<module>mall-spring-boot-starter-mybatis</module>
<module>mall-spring-boot-starter-dubbo</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>

View File

@ -1,132 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-application</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.mall</groupId>-->
<!-- <artifactId>mall-spring-boot</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.mall</groupId>-->
<!-- <artifactId>system-service-impl</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.mall</groupId>-->
<!-- <artifactId>system-sdk</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>cn.iocoder.mall</groupId>-->
<!-- <artifactId>system-service-impl</artifactId>-->
<!-- <version>1.0-SNAPSHOT</version>-->
<!-- </dependency>-->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-business-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-business</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-rpc-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-rpc-service</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<!-- 云服务相关 -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
</dependency>
<!-- 服务保障相关 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 监控相关 -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- 测试相关 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,27 +0,0 @@
package cn.iocoder.mall.demo.application;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication(scanBasePackages = {"cn.iocoder.mall.demo"})
@EnableAsync(proxyTargetClass = true)
//@PropertySource("classpath*:/application-dubbo.yaml")
public class DemoApplication {
/**
* 设置需要读取的配置文件的名字
* 基于 {@link org.springframework.boot.context.config.ConfigFileApplicationListener#CONFIG_NAME_PROPERTY} 实现
*/
private static final String CONFIG_NAME_VALUE = "application,rpc,business";
public static void main(String[] args) {
// 设置环境变量
System.setProperty(ConfigFileApplicationListener.CONFIG_NAME_PROPERTY, CONFIG_NAME_VALUE);
// 启动 Spring Boot 应用
SpringApplication.run(DemoApplication.class, args);
}
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.mall.demo.application.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.demo.application.convert.DemoOrderConvert;
import cn.iocoder.mall.demo.application.dto.DemoOrderAddDTO;
import cn.iocoder.mall.demo.business.api.DemoOrderService;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderAddBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
public class DemoOrderController {
@Autowired
private DemoOrderService demoOrderService;
@PostMapping("/add")
public CommonResult<Integer> add(DemoOrderAddDTO addDTO) {
DemoOrderAddBO addBO = DemoOrderConvert.INSTANCE.convert(addDTO);
addBO.setUserId(10); // TODO 10 用户编号
Integer orderId = demoOrderService.add(addBO);
return CommonResult.success(orderId);
}
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.mall.demo.application.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.demo.application.convert.DemoProductConvert;
import cn.iocoder.mall.demo.application.vo.DemoProductVO;
import cn.iocoder.mall.demo.business.api.DemoProductService;
import cn.iocoder.mall.demo.business.bo.product.DemoProductBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/product")
public class DemoProductController {
@Autowired
private DemoProductService productService;
@GetMapping("/get")
public CommonResult<DemoProductVO> get(@RequestParam("id") Integer id) {
DemoProductBO product = productService.get(id);
return CommonResult.success(DemoProductConvert.INSTANCE.convert(product));
}
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.mall.demo.application.controller;
import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.demo.application.convert.DemoUserConvert;
import cn.iocoder.mall.demo.application.vo.DemoUserVO;
import cn.iocoder.mall.demo.rpc.api.DemoUserRpcService;
import cn.iocoder.mall.demo.rpc.dto.DemoUserDTO;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class DemoUserController {
@Reference(validation = "true", version = "${dubbo.consumer.DemoUserRpcService.version}")
private DemoUserRpcService userRpcService;
// TODO 芋艿这里只是做一个 demo 实际一般不会这么玩更多是内嵌的 {@link #get(Integer id)} 的情况
@GetMapping("/get")
public CommonResult<DemoUserVO> get(@RequestParam("id") Integer id) {
DemoUserDTO user = userRpcService.get(id);
return CommonResult.success(DemoUserConvert.INSTANCE.convert(user));
}
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.application.convert;
import cn.iocoder.mall.demo.application.dto.DemoOrderAddDTO;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderAddBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoOrderConvert {
DemoOrderConvert INSTANCE = Mappers.getMapper(DemoOrderConvert.class);
@Mappings({})
DemoOrderAddBO convert(DemoOrderAddDTO addDTO);
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.application.convert;
import cn.iocoder.mall.demo.application.vo.DemoProductVO;
import cn.iocoder.mall.demo.business.bo.product.DemoProductBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoProductConvert {
DemoProductConvert INSTANCE = Mappers.getMapper(DemoProductConvert.class);
@Mappings({})
DemoProductVO convert(DemoProductBO object);
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.application.convert;
import cn.iocoder.mall.demo.application.vo.DemoUserVO;
import cn.iocoder.mall.demo.rpc.dto.DemoUserDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoUserConvert {
DemoUserConvert INSTANCE = Mappers.getMapper(DemoUserConvert.class);
@Mappings({})
DemoUserVO convert(DemoUserDTO vo);
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.mall.demo.application.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("Demo 订单添加 DTO")
@Data
public class DemoOrderAddDTO {
@ApiModelProperty(value = "商品编号", required = true, example = "1")
private Integer productId;
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.mall.demo.application.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("Demo 商品 BO")
@Data
public class DemoProductVO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "华为 Mate30 Pro", required = true, example = "小王")
private String name;
@ApiModelProperty(value = "价格,单位:分", required = true, example = "10")
private Integer price;
@ApiModelProperty(value = "库存数量", required = true, example = "100")
private Integer quantity;
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.mall.demo.application.vo;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class DemoUserVO {
/**
* 用户编号
*/
private Integer id;
/**
* 昵称
*/
private String name;
/**
* 性别
*/
private Integer gender;
}

View File

@ -1,15 +0,0 @@
dubbo:
application:
name: demo-service
registry:
address: zookeeper://127.0.0.1:2181
protocol:
port: -1
name: dubbo
scan:
base-packages: cn.iocoder.mall.demo.rpc.service
consumer:
DemoProductRpcService:
version: 1.0.0
DemoUserRpcService:
version: 1.0.0

View File

@ -1,12 +0,0 @@
# spring
spring:
application:
name: demo-application
profiles:
active: local
# server
server:
port: 8080
servlet:
context-path: /demo-api/

View File

@ -1,12 +0,0 @@
package cn.iocoder.mall.demo.business.api;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderAddBO;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderCancelBO;
public interface DemoOrderService {
int add(DemoOrderAddBO addBO);
int cancel(DemoOrderCancelBO cancelBO);
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.mall.demo.business.api;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.demo.business.bo.product.*;
public interface DemoProductService {
DemoProductBO get(Integer id);
PageResult<DemoProductBO> page(DemoProductPageBO page);
int add(DemoProductAddBO product);
int update(DemoProductUpdateBO product);
// void updateQuantityIncrease();
void updateQuantityReduce(DemoProductQuantityReduceBO reduceBO);
}

View File

@ -1,9 +0,0 @@
package cn.iocoder.mall.demo.business.api;
import cn.iocoder.mall.demo.business.bo.user.DemoUserBO;
public interface DemoUserService {
DemoUserBO get(Integer id);
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.mall.demo.business.bo.order;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotNull;
/**
* Demo 订单添加 BO
*/
@Data
@Accessors(chain = true)
public class DemoOrderAddBO {
@NotNull(message = "用户编号不能为空")
private Integer userId;
@NotNull(message = "用户编号不能为空")
private Integer productId;
}

View File

@ -1,4 +0,0 @@
package cn.iocoder.mall.demo.business.bo.order;
public class DemoOrderCancelBO {
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.mall.demo.business.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Demo 商品添加 BO
*/
@Data
@Accessors(chain = true)
public class DemoProductAddBO {
/**
* 名字
*/
private String name;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.mall.demo.business.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Demo 商品 BO
*/
@Data
@Accessors(chain = true)
public class DemoProductBO {
/**
* 编号
*/
private Integer id;
/**
* 名字
*/
private String name;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
}

View File

@ -1,13 +0,0 @@
package cn.iocoder.mall.demo.business.bo.product;
import cn.iocoder.common.framework.vo.PageParam;
public class DemoProductPageBO extends PageParam {
/**
* 名字模糊搜索
*/
private String name;
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.mall.demo.business.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/**
* Demo 商品库存减少 BO
*/
@Data
@Accessors(chain = true)
public class DemoProductQuantityReduceBO {
/**
* 商品编号
*/
@NotNull(message = "商品编号不能为空")
private Integer id;
/**
* 减少数量
*/
@NotNull(message = "减少数量不能为空")
@Min(value = 1, message = "减少数量最小为 1")
private Integer quantity;
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.mall.demo.business.bo.product;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Demo 商品更新 BO
*/
@Data
@Accessors(chain = true)
public class DemoProductUpdateBO {
/**
* 编号
*/
private Integer id;
/**
* 名字
*/
private String name;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
}

View File

@ -1,26 +0,0 @@
package cn.iocoder.mall.demo.business.bo.user;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Demo 用户 BO
*/
@Data
@Accessors(chain = true)
public class DemoUserBO {
/**
* 用户编号
*/
private Integer id;
/**
* 昵称
*/
private String name;
/**
* 性别
*/
private Integer gender;
}

View File

@ -1,38 +0,0 @@
package cn.iocoder.mall.demo.business.constant;
/**
* 订单 - status
*
* @author Sin
* @time 2019-03-16 14:06
*/
public enum OrderStatusEnum {
WAITING_PAYMENT(1, "等待付款"),
WAIT_SHIPMENT(2, "等待发货"),
ALREADY_SHIPMENT(3, "已发货"),
COMPLETED(4, "已完成"),
CLOSED(5, "已关闭");
/**
* 状态值
*/
private Integer value;
/**
* 状态名
*/
private String name;
OrderStatusEnum(int value, String name) {
this.value = value;
this.name = name;
}
public int getValue() {
return value;
}
public String getName() {
return name;
}
}

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.business;

View File

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-business</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-business-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- DB 相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.business.cacheobject;

View File

@ -1,26 +0,0 @@
package cn.iocoder.mall.demo.business.cacheobject.user;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 用户缓存对象
*/
@Data
@Accessors(chain = true)
public class DemoUserCacheObject {
/**
* 用户编号
*/
private Integer id;
/**
* 昵称
*/
private String name;
/**
* 性别
*/
private Integer gender;
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.mall.demo.business.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
@Configuration
@MapperScan("cn.iocoder.mall.demo.business.dao") // 扫描对应的 Mapper 接口
@EnableTransactionManagement(proxyTargetClass = true) // 启动事务管理为什么使用 proxyTargetClass 参数参见 https://blog.csdn.net/huang_550/article/details/76492600
public class DatabaseConfiguration {
// 数据源使用 Druid
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.business.convert;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderAddBO;
import cn.iocoder.mall.demo.business.dataobject.order.DemoOrderDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoOrderConvert {
DemoOrderConvert INSTANCE = Mappers.getMapper(DemoOrderConvert.class);
@Mappings({})
DemoOrderDO convert(DemoOrderAddBO object);
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.business.convert;
import cn.iocoder.mall.demo.business.bo.product.DemoProductBO;
import cn.iocoder.mall.demo.business.dataobject.product.DemoProductDO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoProductConvert {
DemoProductConvert INSTANCE = Mappers.getMapper(DemoProductConvert.class);
@Mappings({})
DemoProductBO convert(DemoProductDO object);
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.business.convert;
import cn.iocoder.mall.demo.business.bo.user.DemoUserBO;
import cn.iocoder.mall.demo.business.cacheobject.user.DemoUserCacheObject;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoUserConvert {
DemoUserConvert INSTANCE = Mappers.getMapper(DemoUserConvert.class);
@Mappings({})
DemoUserBO convert(DemoUserCacheObject object);
}

View File

@ -1,10 +0,0 @@
package cn.iocoder.mall.demo.business.dao.mysql;
import cn.iocoder.mall.demo.business.dataobject.order.DemoOrderDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
@Repository
public interface DemoOrderMapper extends BaseMapper<DemoOrderDO> {
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.mall.demo.business.dao.mysql;
import cn.iocoder.mall.demo.business.dataobject.product.DemoProductDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface DemoProductMapper extends BaseMapper<DemoProductDO> {
int updateQuantityReduce(@Param("id") Integer id,
@Param("quantity") Integer quantity);
}

View File

@ -1,31 +0,0 @@
package cn.iocoder.mall.demo.business.dao.redis;
import cn.iocoder.mall.demo.business.cacheobject.user.DemoUserCacheObject;
import com.alibaba.fastjson.JSON;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;
import javax.annotation.Resource;
@Repository
public class DemoUserCacheDao {
private static final String KEY_PREFIX = "user_";
@Resource(name = "redisTemplate")
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
private ValueOperations<String, String> operations;
private static String buildKey(Integer id) {
return KEY_PREFIX + id;
}
public DemoUserCacheObject get(Integer id) {
return JSON.parseObject(operations.get(buildKey(id)), DemoUserCacheObject.class);
}
public void set(Integer id, DemoUserCacheObject value) {
operations.set(buildKey(id), JSON.toJSONString(value));
}
}

View File

@ -1,42 +0,0 @@
package cn.iocoder.mall.demo.business.dataobject.order;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Demo 订单
*/
@Data
@Accessors(chain = true)
@TableName(value = "orders")
public class DemoOrderDO extends DeletableDO {
/**
* id
*/
private Integer id;
/**
* 用户编号
*/
private Integer userId;
/**
* 商品编号
*/
private Integer productId;
/**
* 状态
*
* - 1待付款
* - 2待发货
* - 3待收获
* - 4已完成
* - 5已关闭
*/
private Integer status;
}

View File

@ -1,35 +0,0 @@
package cn.iocoder.mall.demo.business.dataobject.product;
import cn.iocoder.common.framework.dataobject.DeletableDO;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* Demo 商品
*/
@Data
@Accessors(chain = true)
@TableName(value = "product")
public class DemoProductDO extends DeletableDO {
/**
* 编号
*/
private Integer id;
/**
* 名字
*/
private String name;
/**
* 价格
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
}

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.business;

View File

@ -1,58 +0,0 @@
package cn.iocoder.mall.demo.business.service;
import cn.iocoder.common.framework.enums.DeletedStatusEnum;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.mall.demo.business.api.DemoOrderService;
import cn.iocoder.mall.demo.business.api.DemoProductService;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderAddBO;
import cn.iocoder.mall.demo.business.bo.order.DemoOrderCancelBO;
import cn.iocoder.mall.demo.business.bo.product.DemoProductBO;
import cn.iocoder.mall.demo.business.bo.product.DemoProductQuantityReduceBO;
import cn.iocoder.mall.demo.business.constant.OrderStatusEnum;
import cn.iocoder.mall.demo.business.convert.DemoOrderConvert;
import cn.iocoder.mall.demo.business.dao.mysql.DemoOrderMapper;
import cn.iocoder.mall.demo.business.dataobject.order.DemoOrderDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DemoOrderServiceImpl implements DemoOrderService {
@Autowired
private DemoProductService demoProductService;
@Autowired
private DemoOrderMapper demoOrderMapper;
@Override
public int add(DemoOrderAddBO addBO) {
// 产品信息
DemoProductBO productBO = demoProductService.get(addBO.getProductId());
if (productBO == null) { // 商品不存在
throw ServiceExceptionUtil.exception(100000); // TODO 芋艿错误码
}
int quantity = 1;
if (productBO.getQuantity() < quantity) { // 库存不够
throw ServiceExceptionUtil.exception(100001); // TODO 芋艿错误码
}
// 扣除库存
demoProductService.updateQuantityReduce(new DemoProductQuantityReduceBO()
.setId(addBO.getProductId()).setQuantity(quantity));
// 创建订单
DemoOrderDO orderDO = DemoOrderConvert.INSTANCE.convert(addBO);
orderDO.setStatus(OrderStatusEnum.WAITING_PAYMENT.getValue())
.setDeleted(DeletedStatusEnum.DELETED_NO.getValue());
demoOrderMapper.insert(orderDO);
// 返回订单编号
return orderDO.getId();
}
@Override
public int cancel(DemoOrderCancelBO cancelBO) {
return 0;
}
}

View File

@ -1,48 +0,0 @@
package cn.iocoder.mall.demo.business.service;
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
import cn.iocoder.common.framework.vo.PageResult;
import cn.iocoder.mall.demo.business.api.DemoProductService;
import cn.iocoder.mall.demo.business.bo.product.*;
import cn.iocoder.mall.demo.business.convert.DemoProductConvert;
import cn.iocoder.mall.demo.business.dao.mysql.DemoProductMapper;
import cn.iocoder.mall.demo.business.dataobject.product.DemoProductDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DemoProductServiceImpl implements DemoProductService {
@Autowired
private DemoProductMapper demoProductMapper;
@Override
public DemoProductBO get(Integer id) {
DemoProductDO product = demoProductMapper.selectById(id);
return DemoProductConvert.INSTANCE.convert(product);
}
@Override
public PageResult<DemoProductBO> page(DemoProductPageBO page) {
return null;
}
@Override
public int add(DemoProductAddBO product) {
return 0;
}
@Override
public int update(DemoProductUpdateBO product) {
return 0;
}
@Override
public void updateQuantityReduce(DemoProductQuantityReduceBO reduceBO) {
int updateCount = demoProductMapper.updateQuantityReduce(reduceBO.getId(), reduceBO.getQuantity());
if (updateCount == 0) {
throw ServiceExceptionUtil.exception(20000); // TODO 芋艿错误码
}
}
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.mall.demo.business.service;
import cn.iocoder.mall.demo.business.api.DemoUserService;
import cn.iocoder.mall.demo.business.bo.user.DemoUserBO;
import cn.iocoder.mall.demo.business.cacheobject.user.DemoUserCacheObject;
import cn.iocoder.mall.demo.business.convert.DemoUserConvert;
import cn.iocoder.mall.demo.business.dao.redis.DemoUserCacheDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DemoUserServiceImpl implements DemoUserService {
@Autowired
private DemoUserCacheDao userCacheDao;
@Override
public DemoUserBO get(Integer id) {
DemoUserCacheObject userCacheObject = userCacheDao.get(id);
if (userCacheObject == null) { // TODO 芋艿临时
userCacheDao.set(id, new DemoUserCacheObject().setId(id)
.setName("芋艿").setGender(1));
}
return DemoUserConvert.INSTANCE.convert(userCacheObject);
}
}

View File

@ -1,22 +0,0 @@
spring:
# datasource
datasource:
url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8
driver-class-name: com.mysql.jdbc.Driver
username: testb5f4
password: F4df4db0ed86@11
# redis
redis:
# mybatis-plus
mybatis-plus:
configuration:
map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
global-config:
db-config:
id-type: auto
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
mapperLocations: classpath*:mapper/*.xml
typeAliasesPackage: cn.iocoder.mall.demo.business.dataobject

View File

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.mall.demo.business.dao.mysql.DemoProductMapper">
<update id="updateQuantityReduce">
UPDATE product
SET quantity = quantity - #{quantity}
WHERE id = #{id}
AND quantity >= #{quantity}
</update>
</mapper>

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-job</artifactId>
</project>

View File

@ -1,4 +0,0 @@
package cn.iocoder.mall.demo.job.handler;
public class DemoJobHandler {
}

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.job;

View File

@ -1,15 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-mq</artifactId>
</project>

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.mq;

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>demo-rpc-service-api</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>common-framework</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,9 +0,0 @@
package cn.iocoder.mall.demo.rpc.api;
import cn.iocoder.mall.demo.rpc.dto.DemoProductDTO;
public interface DemoProductRpcService {
DemoProductDTO get(Integer id);
}

View File

@ -1,9 +0,0 @@
package cn.iocoder.mall.demo.rpc.api;
import cn.iocoder.mall.demo.rpc.dto.DemoUserDTO;
public interface DemoUserRpcService {
DemoUserDTO get(Integer id);
}

View File

@ -1,22 +0,0 @@
package cn.iocoder.mall.demo.rpc.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ApiModel("Demo 商品 DTO")
@Data
public class DemoProductDTO {
@ApiModelProperty(value = "编号", required = true, example = "1")
private Integer id;
@ApiModelProperty(value = "华为 Mate30 Pro", required = true, example = "小王")
private String name;
@ApiModelProperty(value = "价格,单位:分", required = true, example = "10")
private Integer price;
@ApiModelProperty(value = "库存数量", required = true, example = "100")
private Integer quantity;
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.mall.demo.rpc.dto;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class DemoUserDTO {
/**
* 用户编号
*/
private Integer id;
/**
* 昵称
*/
private String name;
/**
* 性别
*/
private Integer gender;
}

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.rpc;

View File

@ -1,65 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo-rpc-service</artifactId>
<dependencies>
<!-- Mall 相关 -->
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-rpc-service-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-business-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>demo-business</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Registry 和 Config 相关 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.rpc.convert;
import cn.iocoder.mall.demo.business.bo.product.DemoProductBO;
import cn.iocoder.mall.demo.rpc.dto.DemoProductDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoProductConvert {
DemoProductConvert INSTANCE = Mappers.getMapper(DemoProductConvert.class);
@Mappings({})
DemoProductDTO convert(DemoProductBO object);
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.mall.demo.rpc.convert;
import cn.iocoder.mall.demo.business.bo.user.DemoUserBO;
import cn.iocoder.mall.demo.rpc.dto.DemoUserDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper
public interface DemoUserConvert {
DemoUserConvert INSTANCE = Mappers.getMapper(DemoUserConvert.class);
@Mappings({})
DemoUserDTO convert(DemoUserBO object);
}

View File

@ -1 +0,0 @@
package cn.iocoder.mall.demo.rpc;

View File

@ -1,23 +0,0 @@
package cn.iocoder.mall.demo.rpc.service;
import cn.iocoder.mall.demo.business.api.DemoProductService;
import cn.iocoder.mall.demo.business.bo.product.DemoProductBO;
import cn.iocoder.mall.demo.rpc.api.DemoProductRpcService;
import cn.iocoder.mall.demo.rpc.convert.DemoProductConvert;
import cn.iocoder.mall.demo.rpc.dto.DemoProductDTO;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
@Service(validation = "true", version = "${dubbo.provider.DemoProductRpcService.version}")
public class DemoProductRpcServiceImpl implements DemoProductRpcService {
@Autowired
private DemoProductService productService;
@Override
public DemoProductDTO get(Integer id) {
DemoProductBO product = productService.get(id);
return DemoProductConvert.INSTANCE.convert(product);
}
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.mall.demo.rpc.service;
import cn.iocoder.mall.demo.business.api.DemoUserService;
import cn.iocoder.mall.demo.business.bo.user.DemoUserBO;
import cn.iocoder.mall.demo.rpc.api.DemoUserRpcService;
import cn.iocoder.mall.demo.rpc.convert.DemoUserConvert;
import cn.iocoder.mall.demo.rpc.dto.DemoUserDTO;
import org.apache.dubbo.config.annotation.Service;
import org.springframework.beans.factory.annotation.Autowired;
@Service(validation = "true", version = "${dubbo.provider.DemoUserRpcService.version}")
public class DemoUserRpcServiceImpl implements DemoUserRpcService {
@Autowired
private DemoUserService demoUserService;
@Override
public DemoUserDTO get(Integer id) {
DemoUserBO userBO = demoUserService.get(id);
return DemoUserConvert.INSTANCE.convert(userBO);
}
}

View File

@ -1,20 +0,0 @@
# dubbo
dubbo:
application:
name: demo-service
registry:
address: zookeeper://127.0.0.1:2181
protocol:
port: -1
name: dubbo
scan:
base-packages: cn.iocoder.mall.demo.rpc.service
# consumer:
# ProductSpuService:
# version: 1.0.0
provider:
# filter: -exception
DemoProductRpcService:
version: 1.0.0
DemoUserRpcService:
version: 1.0.0

View File

@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>onemall</artifactId>
<groupId>cn.iocoder.mall</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>demo</artifactId>
<packaging>pom</packaging>
<modules>
<module>demo-application</module>
<module>demo-rpc-service-api</module>
<module>demo-rpc-service</module>
<module>demo-business-api</module>
<module>demo-business</module>
<module>demo-job</module>
<module>demo-mq</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-dependencies</artifactId>
<version>1.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>

View File

@ -12,39 +12,60 @@
<artifactId>mall-dependencies</artifactId>
<packaging>pom</packaging>
<name>Onemall Dependencies</name>
<name>${project.artifactId}</name>
<description>Maven Bom定义 Onemall 项目的所有依赖的版本</description>
<!-- 属性 -->
<properties>
<spring.boot.version>2.2.4.RELEASE</spring.boot.version>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<resource.delimiter>@</resource.delimiter>
<java.version>1.8</java.version>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
<!-- 统一依赖管理 -->
<spring.boot.version>2.2.5.RELEASE</spring.boot.version>
<spring.cloud.version>Hoxton.SR1</spring.cloud.version>
<spring.cloud.alibaba.version>2.2.1.RELEASE</spring.cloud.alibaba.version>
<!-- Web 相关 -->
<servlet.version>2.5</servlet.version>
<knife4j.version>2.0.2</knife4j.version>
<swagger.version>1.5.21</swagger.version>
<springfox-swagger.version>2.9.2</springfox-swagger.version>
<!-- DB 相关 -->
<mysql-connector-java.version>5.1.46</mysql-connector-java.version>
<druid.version>1.1.16</druid.version>
<mybatis-spring-boot-starter.version>2.0.0</mybatis-spring-boot-starter.version>
<mybatis.version>3.5.1</mybatis.version>
<mybatis-plus.version>3.1.1</mybatis-plus.version>
<spring-boot-starter-data-jest.version>3.2.5.RELEASE</spring-boot-starter-data-jest.version>
<!-- RPC 相关 -->
<dubbo.version>2.7.1</dubbo.version>
<dubbo.version>2.7.6</dubbo.version>
<!-- Job 相关 -->
<xxl-job.version>2.0.1</xxl-job.version>
<!-- Transaction 相关 -->
<seata.version>1.1.0</seata.version>
<!-- 云服务相关 -->
<qiniu.version>7.2.18</qiniu.version>
<yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
<aliyun-java-sdk-core.version>4.1.0</aliyun-java-sdk-core.version>
<!-- 监控相关 -->
<skywalking.version>7.0.0</skywalking.version>
<spring-boot-admin-starter-client.version>2.2.2</spring-boot-admin-starter-client.version>
<!-- 工具类相关 -->
<fastjson.version>1.2.56</fastjson.version>
<hibernate-validator.version>6.0.16.Final</hibernate-validator.version>
<hutool.version>5.2.5</hutool.version>
<spring-boot-starter-data-jest.version>3.2.5.RELEASE</spring-boot-starter-data-jest.version>
<guava.version>27.0.1-jre</guava.version>
<org.projectlombok.version>1.16.14</org.projectlombok.version>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
</properties>
<!-- 依赖管理 -->
<dependencyManagement>
<dependencies>
<!-- Spring 体系提供的基础 bom -->
<!-- 统一依赖管理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
@ -129,9 +150,11 @@
<!-- Web 相关 -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
<version>${servlet.version}</version>
<optional>true</optional>
</dependency>
<dependency>
@ -140,6 +163,22 @@
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>${knife4j.version}</version>
</dependency>
<dependency>
<groupId>cn.iocoder.mall</groupId>
<artifactId>mall-security-annotations</artifactId>
@ -168,6 +207,18 @@
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- Job 相关 -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job.version}</version>
</dependency>
<!-- Transaction 相关 -->
<dependency>
@ -183,13 +234,75 @@
<version>${skywalking.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin-starter-client.version}</version>
</dependency>
<!-- Test 相关 -->
<!--- 日志相关 -->
<!-- 云服务相关 -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId> <!-- 七牛文件服务器 -->
<version>${qiniu.version}</version>
</dependency>
<dependency>
<groupId>com.yunpian.sdk</groupId>
<artifactId>yunpian-java-sdk</artifactId> <!-- 云片短信 -->
<version>${yunpian-java-sdk.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId> <!-- 七牛短信 -->
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<!-- 工具类相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.fasterxml.jackson.core</groupId>-->
<!-- <artifactId>jackson-annotations</artifactId>-->
<!-- <version>${jackson.version}</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>com.fasterxml.jackson.core</groupId>-->
<!-- <artifactId>jackson-databind</artifactId>-->
<!-- <version>${jackson.version}</version>-->
<!-- </dependency>-->
<dependency>
<!-- hutool 工具类-->
<groupId>cn.hutool</groupId>
@ -205,4 +318,42 @@
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source> <!-- or higher, depending on your project -->
<target>${java.version}</target> <!-- or higher, depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -25,7 +25,7 @@ import javax.validation.Valid;
import static cn.iocoder.common.framework.vo.CommonResult.success;
@Api("管理员 API")
@Api(tags = "管理员 API")
@RestController
@RequestMapping("/admin")
@Validated

View File

@ -14,7 +14,7 @@ spring:
# SpringMVC 配置项
mvc:
throw-exception-if-no-handler-found: true # 匹配不到路径时,抛出 NoHandlerFoundException 异常
static-path-pattern: /statics/** # 静态资源的路径
static-path-pattern: /doc.html # 静态资源的路径
# Dubbo 配置项
dubbo:

213
pom.xml
View File

@ -34,217 +34,4 @@
</modules>
<packaging>pom</packaging>
<properties>
<springboot.version>2.2.5.RELEASE</springboot.version>
<spring-boot-admin-starter-client.version>2.2.2</spring-boot-admin-starter-client.version>
<!-- <com.alibab.dubbo.version>2.6.5</com.alibab.dubbo.version>-->
<dubbo.version>2.7.4.1</dubbo.version>
<!-- <dubbo-spring-boot-starter.version>0.2.1.RELEASE</dubbo-spring-boot-starter.version>-->
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
<curator.version>2.13.0</curator.version>
<!-- <curator.version>4.0.1</curator.version>-->
<!-- <zookeeper.version>3.4.14</zookeeper.version>-->
<swagger.version>1.5.21</swagger.version>
<springfox-swagger.version>2.9.2</springfox-swagger.version>
<swagger-bootstrap-ui.version>1.9.3</swagger-bootstrap-ui.version>
<xxl-job.version>2.0.1</xxl-job.version>
<guava.version>27.0.1-jre</guava.version>
<maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
<org.projectlombok.version>1.16.14</org.projectlombok.version>
<qiniu.version>7.2.18</qiniu.version>
<servlet.version>2.5</servlet.version>
<!-- 短信平台 阿里云、云片 -->
<yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
<aliyun-java-sdk-core.version>4.1.0</aliyun-java-sdk-core.version>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Spring 核心 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${springboot.version}</version>
</dependency>
<!-- Web 相关 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
<version>${servlet.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>${swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>swagger-bootstrap-ui</artifactId>
<version>${swagger-bootstrap-ui.version}</version>
</dependency>
<!-- RPC 相关 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>${dubbo.version}</version>
</dependency>
<!-- DB 相关 -->
<!-- Job 相关 -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${xxl-job.version}</version>
</dependency>
<!-- 短信平台 阿里云、云片 -->
<dependency>
<groupId>com.yunpian.sdk</groupId>
<artifactId>yunpian-java-sdk</artifactId>
<version>${yunpian-java-sdk.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun-java-sdk-core.version}</version>
</dependency>
<!-- 云服务相关 -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu.version}</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>${spring-boot-admin-starter-client.version}</version>
</dependency>
<!-- Test 相关 -->
<!--- 日志相关 -->
<!-- 工具类相关 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId> <!-- use mapstruct-jdk8 for Java 8 or higher -->
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<!--<distributionManagement>-->
<!--<snapshotRepository>-->
<!--<id>apache-snapshots</id>-->
<!--<url>http://repository.apache.org/snapshots/</url>-->
<!--</snapshotRepository>-->
<!--</distributionManagement>-->
<build>
<pluginManagement>
<plugins>
<!-- 提供给 mapstruct 使用 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${java.version}</source> <!-- or higher, depending on your project -->
<target>${java.version}</target> <!-- or higher, depending on your project -->
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- 打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -22,6 +22,11 @@
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@ -73,18 +73,6 @@
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>javax.el</groupId>-->
<!-- <artifactId>javax.el-api</artifactId>-->
<!-- <version>3.0.0</version>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>javax.el</groupId>-->
<!-- <artifactId>javax.el-api</artifactId>-->
<!-- <version>3.0.1-b06</version>-->
<!-- </dependency>-->
</dependencies>
</project>

View File

@ -1,12 +1,10 @@
package cn.iocoder.mall.systemservice.service.admin.bo;
import cn.iocoder.common.framework.vo.PageParam;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@ApiModel("管理员分页查询 BO")
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)