From db60a841f3f57ea650d4a9cac145aab7e041e20d Mon Sep 17 00:00:00 2001 From: Helius <wangdoubleone@gmail.com> Date: Mon, 21 Dec 2020 16:25:45 +0800 Subject: [PATCH] add api interface and config --- zq-erp/src/main/java/com/matrix/system/common/interceptor/ApiUserLoginInterceptor.java | 113 ++++++++++++++++ zq-erp/src/main/java/com/matrix/system/api/action/UsersAction.java | 19 ++ zq-erp/pom.xml | 27 +++ zq-erp/src/main/java/com/matrix/system/api/action/ApiCommonAction.java | 68 +++++++++ zq-erp/src/main/java/com/matrix/config/MvcCoreConfig.java | 22 ++ zq-erp/src/main/resources/config/lhx/application.properties | 2 zq-erp/src/main/java/com/matrix/core/exception/GlobalExceptionHandler.java | 34 ++++ zq-erp/src/main/resources/config/application.properties | 2 zq-erp/src/main/java/com/matrix/system/api/action/TestAction.java | 24 +++ zq-erp/src/main/java/com/matrix/system/api/dto/LoginDto.java | 38 +++++ zq-erp/src/main/java/com/matrix/config/SwaggerConfig.java | 57 ++++++++ 11 files changed, 400 insertions(+), 6 deletions(-) diff --git a/zq-erp/pom.xml b/zq-erp/pom.xml index 1898a84..e03a4ed 100644 --- a/zq-erp/pom.xml +++ b/zq-erp/pom.xml @@ -341,6 +341,29 @@ <artifactId>alibaba-dingtalk-service-sdk</artifactId> <version>1.0.1</version> </dependency> + + <!-- swagger2 start --> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>2.9.2</version> + </dependency> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-annotations</artifactId> + <version>1.5.23</version> + </dependency> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-models</artifactId> + <version>1.5.23</version> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>2.9.2</version> + </dependency> + <!-- swagger2 end --> </dependencies> <build> <resources> @@ -354,14 +377,14 @@ <exclude>config/test/*</exclude> <exclude>config/xcx/*</exclude> - <!-- --> + <!-- <exclude>config/config.json</exclude> <exclude>config/application.properties</exclude> <exclude>config/system.properties</exclude> - +--> <exclude>**/*.woff</exclude> <exclude>**/*.woff2</exclude> <exclude>**/*.ttf</exclude> diff --git a/zq-erp/src/main/java/com/matrix/config/MvcCoreConfig.java b/zq-erp/src/main/java/com/matrix/config/MvcCoreConfig.java index 989b5cc..c48dfe0 100644 --- a/zq-erp/src/main/java/com/matrix/config/MvcCoreConfig.java +++ b/zq-erp/src/main/java/com/matrix/config/MvcCoreConfig.java @@ -3,6 +3,7 @@ import com.matrix.core.interceptor.WbeCommonInterceptor; +import com.matrix.system.common.interceptor.ApiUserLoginInterceptor; import com.matrix.system.common.interceptor.HostInterceptor; import com.matrix.system.common.interceptor.SuAuthorityInterceptor; import com.matrix.system.common.interceptor.UserLoginInterceptor; @@ -36,6 +37,9 @@ @Autowired private WbeCommonInterceptor wbeCommonInterceptor; + @Autowired + private ApiUserLoginInterceptor apiUserLoginInterceptor; + /** * 添加拦截器 @@ -46,15 +50,29 @@ */ @Override public void addInterceptors(InterceptorRegistry registry) { + // 手机端拦截 + registry.addInterceptor(apiUserLoginInterceptor) + .addPathPatterns("/api/**") + .excludePathPatterns("/api/common/**"); + // 公共拦截 registry.addInterceptor(wbeCommonInterceptor) .addPathPatterns("/**") .excludePathPatterns("/css/**") .excludePathPatterns("/js/**") .excludePathPatterns("/images/**") - .excludePathPatterns("/plugin/**"); + .excludePathPatterns("/plugin/**") + .excludePathPatterns("/swagger**/**") + .excludePathPatterns("/webjars/**"); // 用户认证拦截 - registry.addInterceptor(userLoginInterceptor).addPathPatterns("/**").excludePathPatterns("/common/**").excludePathPatterns("/resource/**"); + registry.addInterceptor(userLoginInterceptor) + .addPathPatterns("/**") + .excludePathPatterns("/common/**") + .excludePathPatterns("/resource/**") + .excludePathPatterns("/swagger**/**") + .excludePathPatterns("/webjars/**") + .excludePathPatterns("/api/**"); + // url权限拦截 registry.addInterceptor(suAuthorityInterceptor).addPathPatterns("/**/su/**"); //小程序公司与域名对应关系拦截 diff --git a/zq-erp/src/main/java/com/matrix/config/SwaggerConfig.java b/zq-erp/src/main/java/com/matrix/config/SwaggerConfig.java new file mode 100644 index 0000000..d1cc052 --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/config/SwaggerConfig.java @@ -0,0 +1,57 @@ +package com.matrix.config; + +import io.swagger.annotations.Api; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.util.ArrayList; +import java.util.List; + +/** + * @Author wzy + * @Date 2020/5/11 + * @email wangdoubleone@gmail.com + * @Version V1.0 + **/ +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + + @Value("${swagger.enable}") + private boolean swaggerEnable; + + @Bean + public Docket createRestApi(){ + // 添加请求参数,我们这里把token作为请求头部参数传入后端 + ParameterBuilder parameterBuilder = new ParameterBuilder(); + List<Parameter> parameters = new ArrayList<Parameter>(); + parameterBuilder.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header") + .required(false).build(); + parameters.add(parameterBuilder.build()); + return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(swaggerEnable).select().apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) + .paths(PathSelectors.any()).build().globalOperationParameters(parameters); +// .ignoredParameterTypes(MemberEntity.class); + } + + private ApiInfo apiInfo(){ + return new ApiInfoBuilder() + .title("Hive") + .description("This is a restful api document of Hive.") + .version("1.0") + .build(); + } +} diff --git a/zq-erp/src/main/java/com/matrix/core/exception/GlobalExceptionHandler.java b/zq-erp/src/main/java/com/matrix/core/exception/GlobalExceptionHandler.java new file mode 100644 index 0000000..7602e17 --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/core/exception/GlobalExceptionHandler.java @@ -0,0 +1,34 @@ +package com.matrix.core.exception; + +import com.matrix.core.pojo.AjaxResult; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import javax.validation.ValidationException; + +/** + * @author wzy + * @date 2020-05-08 15:40 + **/ +@RestControllerAdvice +public class GlobalExceptionHandler { + + /** + * 方法参数校验 + * + * @param e + * @return + */ + @ExceptionHandler(value = {MethodArgumentNotValidException.class}) + public AjaxResult handleException(MethodArgumentNotValidException e) { + FieldError fieldError = e.getBindingResult().getFieldError(); + if (fieldError != null) { + return AjaxResult.buildFailInstance(fieldError.getDefaultMessage()); + } else { + return AjaxResult.buildFailInstance("参数校验失败"); + } + } + +} diff --git a/zq-erp/src/main/java/com/matrix/system/api/action/ApiCommonAction.java b/zq-erp/src/main/java/com/matrix/system/api/action/ApiCommonAction.java new file mode 100644 index 0000000..765809d --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/system/api/action/ApiCommonAction.java @@ -0,0 +1,68 @@ +package com.matrix.system.api.action; + +import com.alibaba.fastjson.JSONObject; +import com.matrix.component.redis.RedisClient; +import com.matrix.core.pojo.AjaxResult; +import com.matrix.core.tools.UUIDUtil; +import com.matrix.system.api.dto.LoginDto; +import com.matrix.system.common.authority.DefaultAuthorityManager; +import com.matrix.system.common.authority.strategy.AccountPasswordLogin; +import com.matrix.system.common.authority.strategy.LoginStrategy; +import com.matrix.system.common.bean.SysUsers; +import com.matrix.system.common.service.SysUsersService; +import com.matrix.system.hive.service.SysShopInfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +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; + +/** + * @author wzy + * @date 2020-12-21 + **/ +@Api(value = "CommonAction", tags = "手机端公共请求类(含登陆)") +@RestController +@RequestMapping(value = "/api/common") +public class ApiCommonAction { + + @Autowired + private SysUsersService sysUsersService; + + @Autowired + private SysShopInfoService sysShopInfoService; + + @Autowired + private DefaultAuthorityManager authorityManager; + + @Autowired + private RedisClient redisClient; + + @ApiOperation(value = "登陆接口", notes = "手机端登陆接口") + @PostMapping(value = "/login") + public AjaxResult login(@RequestBody @Validated LoginDto loginDto) { + + SysUsers user = new SysUsers(); + user.setSuAccount(loginDto.getUsername()); + user.setSuPassword(loginDto.getPassword()); + LoginStrategy apLogin = new AccountPasswordLogin(user, sysUsersService); + user = authorityManager.login(apLogin); + + if(user.getShopId()!=null){ + user.setShopName(sysShopInfoService.findById(user.getShopId()).getShopName()); + } + user.setSuPassword(null); + + String token = UUIDUtil.getRandomID(); + redisClient.saveValue(token, JSONObject.toJSONString(user), 360000); + redisClient.saveValue(user.getSuId().toString(), token, 3600000); + + AjaxResult result = new AjaxResult(); + result.putInMap("user", user); + result.setInfo("登陆成功 "); + return result; + } +} diff --git a/zq-erp/src/main/java/com/matrix/system/api/action/TestAction.java b/zq-erp/src/main/java/com/matrix/system/api/action/TestAction.java new file mode 100644 index 0000000..5951110 --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/system/api/action/TestAction.java @@ -0,0 +1,24 @@ +package com.matrix.system.api.action; + +import com.matrix.core.pojo.AjaxResult; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author wzy + * @date 2020-12-21 + **/ +@Api(value = "TestAction", tags = "测试类") +@RestController +@RequestMapping(value = "/api/test") +public class TestAction { + + @ApiOperation(value = "测试请求", notes = "测试请求") + @GetMapping(value = "/testQuery") + public AjaxResult testQuery() { + return null; + } +} diff --git a/zq-erp/src/main/java/com/matrix/system/api/action/UsersAction.java b/zq-erp/src/main/java/com/matrix/system/api/action/UsersAction.java new file mode 100644 index 0000000..92a4aa3 --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/system/api/action/UsersAction.java @@ -0,0 +1,19 @@ +package com.matrix.system.api.action; + +import io.swagger.annotations.Api; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author wzy + * @date 2020-12-21 + **/ +@Api(value = "UsersAction", tags = "用户中心接口类") +@RestController +@RequestMapping(value = "/api/user") +public class UsersAction { + + + + +} diff --git a/zq-erp/src/main/java/com/matrix/system/api/dto/LoginDto.java b/zq-erp/src/main/java/com/matrix/system/api/dto/LoginDto.java new file mode 100644 index 0000000..692a533 --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/system/api/dto/LoginDto.java @@ -0,0 +1,38 @@ +package com.matrix.system.api.dto; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotBlank; + +/** + * @author wzy + * @date 2020-12-21 + **/ +@ApiModel(value = "LoginDto", description = "手机端登陆接收类") +public class LoginDto { + + @ApiModelProperty(value = "用户名", example = "1234") + @NotBlank(message = "用户名或密码错误") + private String username; + + @ApiModelProperty(value = "密码", example = "123456") + @NotBlank(message = "用户名或密码错误") + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/zq-erp/src/main/java/com/matrix/system/common/interceptor/ApiUserLoginInterceptor.java b/zq-erp/src/main/java/com/matrix/system/common/interceptor/ApiUserLoginInterceptor.java new file mode 100644 index 0000000..f783a97 --- /dev/null +++ b/zq-erp/src/main/java/com/matrix/system/common/interceptor/ApiUserLoginInterceptor.java @@ -0,0 +1,113 @@ +package com.matrix.system.common.interceptor; + +import com.alibaba.fastjson.JSONObject; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.matrix.component.redis.RedisClient; +import com.matrix.component.redis.RedisUserLoginUtils; +import com.matrix.core.constance.MatrixConstance; +import com.matrix.core.pojo.AjaxResult; +import com.matrix.core.tools.LogUtil; +import com.matrix.core.tools.RSAUtils; +import com.matrix.core.tools.StringUtils; +import com.matrix.system.common.bean.SysUsers; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author wzy + * @date 2020-12-21 + **/ +@Component +public class ApiUserLoginInterceptor implements HandlerInterceptor { + + @Autowired + private RedisClient redisClient; + + @Value("${login_private_key}") + private String privateKey; + + private final String TOKEN_HEADER = "Authorization"; + private final String TOKEN_START_WITH = "Bearer "; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + String token = resolveToken(request); + AjaxResult ajaxResult = new AjaxResult(); + ajaxResult.setStatus(AjaxResult.STATUS_LOGIN_INVALID); + + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/json; charset=utf-8"); + if (StringUtils.isBlank(token)) { + ajaxResult.setInfo("login time out"); + response.getWriter().write(new ObjectMapper().writeValueAsString(ajaxResult)); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return false; + } + + String userStr = redisClient.getCachedValue(token); + redisClient.resetExpire(token); + if (StringUtils.isBlank(userStr)) { + ajaxResult.setInfo("login time out"); + response.getWriter().write(new ObjectMapper().writeValueAsString(ajaxResult)); + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return false; + } + + SysUsers sysUsers = JSONObject.parseObject(userStr, SysUsers.class); + request.getSession().setAttribute(MatrixConstance.LOGIN_KEY, sysUsers); + return true; + } + + @Override + public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { + request.getSession().removeAttribute(MatrixConstance.LOGIN_KEY); + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + + } + + /** + * 解析token token_timestamp_url + * + * @param request + * @return + */ + private String resolveToken(HttpServletRequest request) { + String headToken = request.getHeader(TOKEN_HEADER); + StringBuffer sb = request.getRequestURL(); + + if (StringUtils.isNotBlank(headToken) && headToken.startsWith(TOKEN_START_WITH)) { + // 去掉令牌前缀 + String rsaToken = headToken.replace(TOKEN_START_WITH, ""); + + try { + String decryptTokten = new String(RSAUtils.decryptByPrivateKey(rsaToken, privateKey)); + + String[] s = decryptTokten.split("_"); + if (s == null || s.length != 3) { + return ""; + } + + if (!sb.toString().equals(s[2])) { + return ""; + } + + return s[0]; + } catch (Exception e) { + LogUtil.info("#token解析错误:{}#", e); + return ""; + } + + } + + return ""; + } +} diff --git a/zq-erp/src/main/resources/config/application.properties b/zq-erp/src/main/resources/config/application.properties index 5df391f..466f6f6 100644 --- a/zq-erp/src/main/resources/config/application.properties +++ b/zq-erp/src/main/resources/config/application.properties @@ -59,7 +59,7 @@ #定时任务 scheduling.enabled=false -swagger.enable=false +swagger.enable=true swagger.security.username=admin swagger.security.password=admin diff --git a/zq-erp/src/main/resources/config/lhx/application.properties b/zq-erp/src/main/resources/config/lhx/application.properties index 3aead90..681f70d 100644 --- a/zq-erp/src/main/resources/config/lhx/application.properties +++ b/zq-erp/src/main/resources/config/lhx/application.properties @@ -57,4 +57,4 @@ #定时任务 scheduling.enabled=true -swagger.enable=false \ No newline at end of file +swagger.enable=true \ No newline at end of file -- Gitblit v1.9.1