Commit 960413c2 authored by libin's avatar libin

Merge branches 'member_statistics' and 'wallet_detail' into dev

...@@ -48,6 +48,11 @@ public class BaseUserMemberExport implements Serializable { ...@@ -48,6 +48,11 @@ public class BaseUserMemberExport implements Serializable {
private Integer beforeDiscount; private Integer beforeDiscount;
@Column(name = "source") @Column(name = "source")
private Integer source; private Integer source;
/**
* 核销时间
*/
@Column(name = "verification_time")
private Long verificationTime;
} }
......
...@@ -91,6 +91,7 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper, ...@@ -91,6 +91,7 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper,
.crtId(userId) .crtId(userId)
.crtName(name) .crtName(name)
.crtTime(Instant.now().toEpochMilli()) .crtTime(Instant.now().toEpochMilli())
.verificationTime(hasUsed?Instant.now().toEpochMilli():0)
.isDel(0) .isDel(0)
.build(); .build();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
...@@ -198,6 +199,7 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper, ...@@ -198,6 +199,7 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper,
.memberName(memberName) .memberName(memberName)
.crtName(userName) .crtName(userName)
.crtTime(Instant.now().toEpochMilli()) .crtTime(Instant.now().toEpochMilli())
.verificationTime(hasUsed?Instant.now().toEpochMilli():null)
.isDel(0) .isDel(0)
.build(); .build();
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {
...@@ -209,7 +211,9 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper, ...@@ -209,7 +211,9 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper,
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void InsertBatch(List<BaseUserMemberExport> baseUserMemberExports) { public void InsertBatch(List<BaseUserMemberExport> baseUserMemberExports) {
mapper.insertList(baseUserMemberExports); for (BaseUserMemberExport userMemberExport : baseUserMemberExports) {
mapper.insertSelective(userMemberExport);
}
} }
public List<BaseUserMemberExportDTO> findUserMemberExportDataByPhoneAndHashEffective(String phone) { public List<BaseUserMemberExportDTO> findUserMemberExportDataByPhoneAndHashEffective(String phone) {
...@@ -235,7 +239,7 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper, ...@@ -235,7 +239,7 @@ public class BaseUserMemberExportBiz extends BaseBiz<BaseUserMemberExportMapper,
@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED) @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
public void updateUserMemberExportDataToLoseEfficacyByPhone(String phone,Integer userId) { public void updateUserMemberExportDataToLoseEfficacyByPhone(String phone,Integer userId) {
mapper.updateUserMemberExportDataToLoseEfficacyByPhone(phone,userId); mapper.updateUserMemberExportDataToLoseEfficacyByPhone(phone,userId,Instant.now().toEpochMilli());
} }
public PageDataVO<BaseUserMemberExportVo> findUserMemberExportDataPage(BaseUserMemberExportDataFindDTO exportDataFindDTO) { public PageDataVO<BaseUserMemberExportVo> findUserMemberExportDataPage(BaseUserMemberExportDataFindDTO exportDataFindDTO) {
......
...@@ -18,7 +18,7 @@ import java.util.List; ...@@ -18,7 +18,7 @@ import java.util.List;
public interface BaseUserMemberExportMapper extends Mapper<BaseUserMemberExport>, InsertListMapper<BaseUserMemberExport> { public interface BaseUserMemberExportMapper extends Mapper<BaseUserMemberExport>, InsertListMapper<BaseUserMemberExport> {
void updateUserMemberExportDataToLoseEfficacyByPhone(@Param("phone") String phone,@Param("userId") Integer userId); void updateUserMemberExportDataToLoseEfficacyByPhone(@Param("phone") String phone,@Param("userId") Integer userId,@Param("time") Long time);
List<BaseUserMemberExportDTO> findExportDataPage(BaseUserMemberExportDataFindDTO exportDataFindDTO); List<BaseUserMemberExportDTO> findExportDataPage(BaseUserMemberExportDataFindDTO exportDataFindDTO);
......
...@@ -14,10 +14,11 @@ ...@@ -14,10 +14,11 @@
<result property="crtName" column="crt_name"/> <result property="crtName" column="crt_name"/>
<result property="crtTime" column="crt_time"/> <result property="crtTime" column="crt_time"/>
<result property="userId" column="user_id"/> <result property="userId" column="user_id"/>
<result property="verificationTime" column="verification_time"/>
</resultMap> </resultMap>
<update id="updateUserMemberExportDataToLoseEfficacyByPhone"> <update id="updateUserMemberExportDataToLoseEfficacyByPhone">
update `base_user_member_export` set `status`=1,`user_id`=#{userId} where `username`=#{phone} update `base_user_member_export` set `status`=1,`user_id`=#{userId},`verification_time`=#{time} where `username`=#{phone}
</update> </update>
<select id="findExportDataPage" resultType="com.github.wxiaoqi.security.admin.dto.BaseUserMemberExportDTO"> <select id="findExportDataPage" resultType="com.github.wxiaoqi.security.admin.dto.BaseUserMemberExportDTO">
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
<modules> <modules>
<module>xx-common-platform</module> <module>xx-common-platform</module>
<module>xx-common-platform-web</module> <module>xx-common-platform-web</module>
<module>xx-common-platform-component</module>
</modules> </modules>
</project> </project>
\ No newline at end of file
<?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>xx-common</artifactId>
<groupId>com.xxfc</groupId>
<version>2.0-SNAPSHOT</version>
<relativePath/>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxfc.platform</groupId>
<artifactId>li</artifactId>
<properties>
<swagger.version>2.9.2</swagger.version>
</properties>
<dependencies>
<dependency>
<groupId>com.github.wxiaoqi</groupId>
<artifactId>ace-admin-api</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-configuration-processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>com.github.wxiaoqi</groupId>
<artifactId>ace-common</artifactId>
<version>2.0-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
<scope>provided</scope>
</dependency>
<!-- cache -->
<dependency>
<groupId>com.github.wxiaoqi</groupId>
<artifactId>ace-cache</artifactId>
<version>0.0.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.ace.cache.parser.impl;
import com.ace.cache.parser.ICacheResultParser;
import com.alibaba.fastjson.JSON;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
/**
* 转map 有问题
*/
public class DefaultResultParser implements ICacheResultParser {
public DefaultResultParser() {
}
public Object parse(String value, Type type, Class<?>... origins) {
Object result = null;
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)type;
Type rawType = parameterizedType.getRawType();
if (((Class)rawType).isAssignableFrom(List.class)) {
result = JSON.parseArray(value, (Class)parameterizedType.getActualTypeArguments()[0]);
}else if(((Class)rawType).isAssignableFrom(Map.class)) {
Map transition = JSON.parseObject(value, Map.class);
transition.forEach((k, v) -> {
transition.put(k, JSON.parseObject(value, (Class)parameterizedType.getActualTypeArguments()[1]));
});
result = transition;
}
} else if (origins == null) {
result = JSON.parseObject(value, (Class)type);
} else {
result = JSON.parseObject(value, origins[0]);
}
return result;
}
}
\ No newline at end of file
package com.xxfc.platform.common.annotaion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author libin
* @version 1.0
* @description 复杂类型校验
* @data 2019/6/13 13:42
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface BeanValid {
Class<?>[] value() default {};
}
package com.xxfc.platform.common.annotaion;
import java.lang.annotation.*;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/8 15:26
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface LoginUser {
}
package com.xxfc.platform.common.annotaion;
import com.xxfc.platform.common.util.RedisLock;
import java.lang.annotation.*;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/8 15:26
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface NoRepeatSubmit {
long timeout() default 10;
String pre() default "";
RedisLock.ExpireTimeUnitEnum exptunit() default RedisLock.ExpireTimeUnitEnum.EXPIRETIME;
}
package com.xxfc.platform.common.annotaion;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface RateLimit {
}
package com.xxfc.platform.common.annotaion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author libin
* @version 1.0
* @description 简单参数类型校验
* @data 2019/6/13 13:42
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface SimpleValid {
}
package com.xxfc.platform.common.aop;
import com.xxfc.platform.common.annotaion.NoRepeatSubmit;
import com.xxfc.platform.common.msg.ApiResult;
import com.xxfc.platform.common.msg.PageApiResult;
import com.xxfc.platform.common.util.RedisLock;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/8 21:04
*/
@Aspect
@Component
@Slf4j
public class NoRepeatSubmitAop {
@Value("${auth.user.token-header:Authorization}")
private String tokenHeader;
private static final String NO_REPEAT_SUBMIT_PREKEY = "no:submit";
@Autowired
private RedisLock redisLock;
@Pointcut("@annotation(noRepeatSubmit)")
public void noRepeateSubmitExpress(NoRepeatSubmit noRepeatSubmit) {}
@Around("noRepeateSubmitExpress(noRepeatSubmit)")
public Object noRepeateSubmitAround(ProceedingJoinPoint proceedingJoinPoint, NoRepeatSubmit noRepeatSubmit) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
String uri = request.getRequestURI();
String token = request.getHeader(tokenHeader);
String lockKey = String.format("%s%s:%s:%s", StringUtils.isEmpty(noRepeatSubmit.pre()) ? "" : noRepeatSubmit.pre() + ":", NO_REPEAT_SUBMIT_PREKEY, token, uri);
boolean tryLock = redisLock.tryLock(lockKey, uri, noRepeatSubmit.exptunit(), noRepeatSubmit.timeout());
Object result = null;
if (tryLock) {
log.info("tryLock success, key=【{}】,接口地址:uri=【{}】", lockKey, uri);
try {
result = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
log.error(throwable.getMessage(), throwable);
} finally {
redisLock.releaseLock(lockKey, uri);
log.info("releassLock success,key=【{}】,接口地址:uri=【{}】", lockKey, uri);
}
return result;
} else {
log.info("tryLock fail key=【{}】", lockKey);
return ApiResult.fail(100001, "获取锁失败");
}
}
}
package com.xxfc.platform.common.aop;
import cn.hutool.core.util.ArrayUtil;
import com.github.wxiaoqi.security.common.annotation.BeanValid;
import com.github.wxiaoqi.security.common.annotation.SimpleValid;
import com.xxfc.platform.common.msg.ApiResult;
import lombok.Data;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Objects;
import java.util.Set;
/**
* @author libin
* @version 1.0
* @description 切面验证
* @data 2019/6/13 13:46
*/
@Aspect
@Data
public class ValidParamAop {
/**
* 复合类型验证器
*/
private Validator validator;
/**
* 简单类型验证器
*/
private ExecutableValidator executableValidator;
@Pointcut("execution(* com.xxfc.platform..rest..*(..))")
public void validatorExpress(){}
@Around("validatorExpress()")
public Object validatorAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
//获取方法的所有参数
Object[] args = proceedingJoinPoint.getArgs();
if (ArrayUtil.isEmpty(args)){
//没有参数,不用验证
return proceedingJoinPoint.proceed();
}
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
Method currentMethod = methodSignature.getMethod();
Parameter[] parameters = currentMethod.getParameters();
boolean hashSimpleValid = false;
int argLength = args.length;
for (int i =0;i<argLength;i++){
BeanValid beanValidAnnotation = parameters[i].getDeclaredAnnotation(BeanValid.class);
if (Objects.nonNull(beanValidAnnotation)){
if (args[i].getClass().isArray()){
Object[] arrayArg =(Object[])args[i];
for (Object item:arrayArg){
Set<ConstraintViolation<Object>> validateResult = this.validator.validate(item, beanValidAnnotation.value());
if (!validateResult.isEmpty()){
String message = validateResult.iterator().next().getMessage();
return ApiResult.fail(400,message);
}
}
}else {
Set<ConstraintViolation<Object>> validateResult = this.validator.validate(args[i], beanValidAnnotation.value());
if (!validateResult.isEmpty()){
String message = validateResult.iterator().next().getMessage();
return ApiResult.fail(400,message);
}
}
continue;
}
if (!hashSimpleValid){
SimpleValid simpleValidAnnotation = parameters[i].getDeclaredAnnotation(SimpleValid.class);
if (Objects.nonNull(simpleValidAnnotation)){
hashSimpleValid = true;
}
}
}
if (hashSimpleValid){
Object target = proceedingJoinPoint.getTarget();
Set<ConstraintViolation<Object>> validResult = this.executableValidator.validateParameters(target, currentMethod, args);
if(!validResult.isEmpty()){
String message = validResult.iterator().next().getMessage();
return ApiResult.fail(400,message);
}
}
return proceedingJoinPoint.proceed();
}
}
package com.xxfc.platform.common.config;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Configuration;
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;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
/**
* @author libin
* @version 1.0
* @description 设置请求头部信息,防止微服务之间调用请求头部信息丢失
* @data 2019/6/25 16:22
*/
public class HeaderConfig implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes instanceof ServletRequestAttributes){
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;
HttpServletRequest request = servletRequestAttributes.getRequest();
//请求头设置
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames!=null){
while (headerNames.hasMoreElements()){
String headerName = headerNames.nextElement();
String headerValue = request.getHeader(headerName);
template.header(headerName,headerValue);
}
}
}
}
}
package com.xxfc.platform.common.config;
import io.swagger.annotations.Api;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Profile;
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 libin
* @version 1.0
* @description 通用swagger设置
* @data 2019/6/26 10:28
*/
@Profile(value = {"dev","test"})
@ConditionalOnClass(value = EnableSwagger2.class)
@ConditionalOnProperty(prefix = "xxfc",name = "swagger",havingValue = "true")
@EnableSwagger2
@Setter
public class SwaggerConfig {
@Value("${xxfc.swagger.title:xxfc api swagger document}")
private String title;
@Value("${xxfc.swagger.description:前后端联调xxfc api 文档}")
private String description;
@Value("${xxfc.swagger.version:1.0.0}")
private String version;
@Value("${jwt.tokenHeader:Authorization}")
private String header;
@Bean
public Docket docket(){
ParameterBuilder ticketPar = new ParameterBuilder();
List<Parameter> parameters = new ArrayList<Parameter>();
ticketPar.name(header).description("user Authorization")
.modelRef(new ModelRef("string")).parameterType("header")
//header中的ticket参数非必填,传空也可以
.required(false).build();
//根据每个方法名也知道当前方法在设置什么参数
parameters.add(ticketPar.build());
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build()
.globalOperationParameters(parameters);
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title(title)
.description(description)
.version(version)
.build();
}
}
package com.xxfc.platform.common.config;
import com.github.wxiaoqi.security.common.support.aop.ValidParamAop;
import org.hibernate.validator.HibernateValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.executable.ExecutableValidator;
/**
* @author libin
* @version 1.0
* @description 验证器validator
* @data 2019/6/13 13:48
*/
@Configuration
public class ValidatorConfig {
/**
* 复合类型所用的验证器
* @return Validator
*/
@Bean
public Validator validator(){
// .failFast( true ) 为设置快速错误模式,默认为false
ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
.configure()
.failFast( true )
.buildValidatorFactory();
return validatorFactory.getValidator();
}
/**
* 简单类型所用的验证器
* @return ExecutableValidator
*/
@Bean
public ExecutableValidator executableValidator() {
return validator().forExecutables();
}
/**
* 装配验证器切面
* @param validator Bean验证器
* @param executableValidator 简单类型验证器
* @return ValidParamAop
*/
@Bean
public ValidParamAop validAop(Validator validator, ExecutableValidator executableValidator) {
ValidParamAop validParamAop = new ValidParamAop();
validParamAop.setValidator(validator);
validParamAop.setExecutableValidator(executableValidator);
return validParamAop;
}
}
package com.xxfc.platform.common.config;
import com.xxfc.platform.common.resover.LoginUserParamResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/9 17:29
*/
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Autowired
private LoginUserParamResolver loginUserParamResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(loginUserParamResolver);
}
}
package com.xxfc.platform.common.msg;
import lombok.Data;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/9 16:55
*/
@Data
public class ApiResult<T> extends BaseApiResult<T> {
private ApiResult(long code, String msg, T data, boolean successResponse, String requestId) {
super(code,msg,data,successResponse,requestId);
}
public static <T> ApiResult<T> ok() {
return new ApiResult(200, "ok", "ok", true, "0");
}
public static <T> ApiResult<T> ok(T data) {
return new ApiResult(200, "ok", data, true, "0");
}
public static <T> ApiResult<T> ok(T data, String requestId) {
return new ApiResult(200, "ok", data, true, requestId);
}
}
package com.xxfc.platform.common.msg;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/9 17:55
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseApiResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
protected long code;
protected String msg;
protected T data;
protected boolean successResponse;
protected String requestId;
public static <T> BaseApiResult<T> fail() {
return new BaseApiResult(400, "fail", "fail", false, "0");
}
public static <T> BaseApiResult<T> fail(String msg) {
return new BaseApiResult(400, msg, "fail", false, "0");
}
public static <T> BaseApiResult<T> fail(long code, String msg) {
return new BaseApiResult(code, msg, "fail", false, "0");
}
}
package com.xxfc.platform.common.msg;
import lombok.Data;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/9 17:45
*/
@Data
public class PageApiResult<T> extends BaseApiResult<T> {
private PageInfo pageInfo;
private PageApiResult(long code, String msg, T data, boolean successResponse, String requestId, PageInfo pageInfo) {
super(code, msg, data, successResponse, requestId);
this.pageInfo = pageInfo;
}
public static <T> PageApiResult<T> ok() {
return new PageApiResult(200, "ok", "ok", true, "0", PageInfo.createEmptyPageInfo());
}
public static <T> PageApiResult<T> ok(T data, PageInfo pageInfo) {
return new PageApiResult(200, "ok", data, true, "0", pageInfo);
}
public static <T> PageApiResult<T> ok(T data, PageInfo pageInfo, String requestId) {
return new PageApiResult(200, "ok", data, true, requestId, pageInfo);
}
@Data
static class PageInfo {
private Integer page;
private Integer pageSize;
private Integer total;
private PageInfo(){}
private PageInfo(Integer page, Integer pageSize, Integer total) {
this.page = page;
this.pageSize = pageSize;
this.total = total;
}
public static PageInfo createEmptyPageInfo() {
return new PageInfo();
}
public static PageInfo createPageInfo(Integer page, Integer pageSize, Integer total) {
return new PageInfo(page,pageSize,total);
}
}
}
package com.xxfc.platform.common.resover;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.admin.feign.dto.AppUserDTO;
import com.github.wxiaoqi.security.admin.feign.dto.UserDTO;
import com.xxfc.platform.common.annotaion.LoginUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpServletRequest;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/8 20:17
*/
@ConditionalOnBean(value = UserFeign.class)
@Component
public class LoginUserParamResolver implements HandlerMethodArgumentResolver {
@Value("${auth.user.token-header:Authorization}")
private String tokenHeader;
@Autowired
private UserFeign userFeign;
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(LoginUser.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
String token = request.getHeader(tokenHeader);
Class<?> parameterType = parameter.getParameterType();
if (AppUserDTO.class.equals(parameterType)){
return userFeign.userDetailByToken(token).getData();
}
if (UserDTO.class.equals(parameterType)){
return userFeign.userinfoByToken(token).getData();
}
return null;
}
}
package com.xxfc.platform.common.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import java.util.Collections;
/**
* @author libin
* @version 1.0
* @description
* @data 2019/7/8 21:02
*/
@Component
public class RedisLock {
private static final Long RELEASE_SUCCESS = 1L;
private static final String LOCK_SUCCESS = "OK";
private static final String SET_IF_NOT_EXIST = "NX";
/**
* if get(key) == value return del(key)
*/
private static final String RELEASE_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
@Autowired
private StringRedisTemplate redisTemplate;
/**
* 该加锁方法仅针对单实例 Redis 可实现分布式加锁
* 对于 Redis 集群则无法使用
* <p>
* 支持重复,线程安全
*
* @param lockKey 加锁键
* @param clientId 加锁客户端唯一标识(采用UUID)
* @param seconds 锁过期时间
* @return
*/
public boolean tryLock(String lockKey, String clientId, ExpireTimeUnitEnum expireTimeEnum,long seconds) {
return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> {
Jedis jedis = (Jedis) redisConnection.getNativeConnection();
String result = jedis.set(lockKey, clientId, SET_IF_NOT_EXIST, expireTimeEnum.getUnit(), seconds);
if (LOCK_SUCCESS.equals(result)) {
return true;
}
return false;
});
}
/**
* 与 tryLock 相对应,用作释放锁
*
* @param lockKey
* @param clientId
* @return
*/
public boolean releaseLock(String lockKey, String clientId) {
return redisTemplate.execute((RedisCallback<Boolean>) redisConnection -> {
Jedis jedis = (Jedis) redisConnection.getNativeConnection();
Object result = jedis.eval(RELEASE_LOCK_SCRIPT, Collections.singletonList(lockKey),
Collections.singletonList(clientId));
if (RELEASE_SUCCESS.equals(result)) {
return true;
}
return false;
});
}
public enum ExpireTimeUnitEnum {
/**
* 当前设置 过期时间单位, EX = seconds; PX = milliseconds
*/
EXPIRETIME("EX"),
PXPIRETIME("PX");
ExpireTimeUnitEnum(String unit) {
this.unit = unit;
}
String unit;
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment