commit
4d5a5032e1
1225 changed files with 84516 additions and 0 deletions
@ -0,0 +1,30 @@ |
||||
# Created by .ignore support plugin (hsz.mobi) |
||||
### Java template |
||||
# Compiled class file |
||||
*.class |
||||
|
||||
# Log file |
||||
*.log |
||||
|
||||
# BlueJ files |
||||
*.ctxt |
||||
|
||||
# Mobile Tools for Java (J2ME) |
||||
.mtj.tmp/ |
||||
|
||||
# Package Files # |
||||
*.jar |
||||
*.war |
||||
*.nar |
||||
*.ear |
||||
*.zip |
||||
*.tar.gz |
||||
*.rar |
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml |
||||
hs_err_pid* |
||||
|
||||
# idea |
||||
*.iml |
||||
target/ |
||||
.idea/ |
@ -0,0 +1,21 @@ |
||||
<?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>blockchain-common</artifactId> |
||||
<groupId>com.blockchain</groupId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>blockchain-common-base</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>com.blockchain</groupId> |
||||
<artifactId>blockchain-common-pom</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
@ -0,0 +1,18 @@ |
||||
package com.blockchain.common.base.constant; |
||||
|
||||
public class BaseConstant { |
||||
public static final String REDIS_TOKEN_KEY = "user:token:";//redis 存储token的key值,用于获取用户信息
|
||||
public static final String REDIS_TOKEN_PC_KEY = "user:token:pc";//redis 存储token的key值,用于获取用户信息
|
||||
public static final String PARAMS_LOCALE = "locale";//中英文参数
|
||||
public static final String SSO_TOKEN_HEADER = "X-Requested-Token";//sso单点登录的header
|
||||
|
||||
public static final String PAGE_DEFAULT_SIZE = "10";//分页默认查询条数
|
||||
public static final String PAGE_DEFAULT_INDEX = "1";//分页默认查询起始页
|
||||
|
||||
public static final String USER_LOCALE_ZH_CN = "zh_CN";//中文
|
||||
public static final String USER_LOCALE_EN_US = "en_US";//英文
|
||||
public static final String USER_LOCALE_ZH_HK = "zh_HK";//繁体中文
|
||||
public static final String USER_LOCALE_DEFAULT = USER_LOCALE_ZH_CN;//默认国际化标识为繁体中文
|
||||
|
||||
public static final int REQUEST_SUCCESS = 200;// 成功标识
|
||||
} |
@ -0,0 +1,11 @@ |
||||
package com.blockchain.common.base.constant; |
||||
|
||||
/**** |
||||
* 推送通知的透传参数Key常量 |
||||
*/ |
||||
public class PushConstants { |
||||
|
||||
public static final String ORDER_ID = "orderId"; //币币交易和法币交易的订单Id常量
|
||||
public static final String AD_ID = "adId"; //法币交易的广告Id常量
|
||||
public static final String PUSH_TYPE = "pushType"; //推送触发类型
|
||||
} |
@ -0,0 +1,24 @@ |
||||
package com.blockchain.common.base.constant; |
||||
|
||||
/** |
||||
* \* <p>Desciption:汇率枚举</p> |
||||
* \* CreateTime: 2019/3/21 20:00 |
||||
* \* User: XianChaoWei |
||||
* \* Version: V1.0 |
||||
* \ |
||||
*/ |
||||
public enum TokenTypeEnums { |
||||
APP("APP"), |
||||
PC("PC") |
||||
; |
||||
|
||||
private String value; |
||||
|
||||
TokenTypeEnums(String value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
public String getValue() { |
||||
return value; |
||||
} |
||||
} |
@ -0,0 +1,6 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
public class BaseDTO implements Serializable { |
||||
} |
@ -0,0 +1,17 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
/** |
||||
* GasDTO 手续费公用类 |
||||
*/ |
||||
@Data |
||||
public class GasDTO extends BaseDTO { |
||||
private BigDecimal gasPrice; // 手续费
|
||||
private String gasTokenType; // 币种识别标识
|
||||
private String gasTokenSymbol; // 币种名称
|
||||
private String gasTokenName; // 币种名称
|
||||
private BigDecimal minWdAmount; // 最小提现余额
|
||||
} |
@ -0,0 +1,22 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
/*** |
||||
* 交易盘口列表DTO |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class MarketDTO { |
||||
private BigDecimal unitPrice; //单价
|
||||
private BigDecimal totalNum; //总数量
|
||||
private BigDecimal totalLastNum; //总剩余数量
|
||||
private String unitName; //二级货币
|
||||
private String coinName; //基本货币
|
||||
private String tradingType; //交易方向
|
||||
} |
@ -0,0 +1,54 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.util.List; |
||||
|
||||
@Data |
||||
public class PageDTO<T> extends BaseDTO { |
||||
/* 总条目数 */ |
||||
private Long total; |
||||
/* 当前页码 */ |
||||
private Integer pageNum; |
||||
/* 每页记录数 */ |
||||
private Integer pageSize; |
||||
/* 第一页页码 */ |
||||
private Integer firstPage; |
||||
/* 上一页页码 */ |
||||
private Integer prePage; |
||||
/* 下一页页码 */ |
||||
private Integer nextPage; |
||||
/* 最后一页页码,最大页数 */ |
||||
private Integer lastPage; |
||||
/* 结果集 */ |
||||
private List<T> rows; |
||||
|
||||
/** |
||||
* 构造函数 |
||||
* |
||||
* @param total : 总数 |
||||
* @param pageNum : 当前页数 |
||||
* @param pageSize : 页数大小 |
||||
* @param rows : 集合 |
||||
*/ |
||||
public PageDTO(Long total, Integer pageNum, Integer pageSize, List<T> rows) { |
||||
this.total = total; |
||||
this.pageSize = pageSize; |
||||
this.rows = rows; |
||||
if (total == null || total == 0) { |
||||
this.total = 0l; |
||||
this.pageNum = 1; |
||||
this.firstPage = 1; |
||||
this.prePage = 1; |
||||
this.nextPage = 1; |
||||
this.lastPage = 1; |
||||
} else { |
||||
this.pageNum = pageNum; |
||||
this.firstPage = 1; |
||||
long pageTotal = total / pageSize; |
||||
this.lastPage = (int) ((total % pageSize == 0) ? pageTotal : pageTotal + 1); |
||||
this.prePage = this.pageNum - 1; |
||||
this.nextPage = this.pageNum == lastPage ? 0 : this.pageNum + 1; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,49 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.util.HttpRequestUtil; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
/** |
||||
* 统一数据返回格式 |
||||
*/ |
||||
@Data |
||||
@NoArgsConstructor |
||||
@AllArgsConstructor |
||||
public class ResultDTO<T> extends BaseDTO { |
||||
private int code;//返回码
|
||||
private String msg;//返回码描述
|
||||
private T data;//返回数据
|
||||
|
||||
public static ResultDTO requstSuccess() { |
||||
return requstSuccess(null); |
||||
} |
||||
|
||||
public static ResultDTO requstSuccess(Object data) { |
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
||||
String userLocale = BaseConstant.USER_LOCALE_DEFAULT; |
||||
if (request != null) { |
||||
userLocale = HttpRequestUtil.getUserLocale(request); |
||||
} |
||||
String msg; |
||||
switch (userLocale) { |
||||
case BaseConstant.USER_LOCALE_EN_US: |
||||
msg = BaseResultEnums.SUCCESS.getEnMsg(); |
||||
break; |
||||
case BaseConstant.USER_LOCALE_ZH_CN: |
||||
msg = BaseResultEnums.SUCCESS.getCnmsg(); |
||||
break; |
||||
default: |
||||
msg = BaseResultEnums.SUCCESS.getHkmsg(); |
||||
break; |
||||
} |
||||
return new ResultDTO(BaseResultEnums.SUCCESS.getCode(), msg, data); |
||||
} |
||||
} |
@ -0,0 +1,15 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* 放到session里的用户 |
||||
*/ |
||||
@Data |
||||
public class SessionUserDTO extends BaseDTO{ |
||||
private String id;//用户id
|
||||
private String tel;//手机号
|
||||
private Long timestamp;//时间戳
|
||||
} |
@ -0,0 +1,18 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
|
||||
import lombok.Data; |
||||
|
||||
/** |
||||
* \* <p>Desciption:</p> |
||||
* \* CreateTime: 2018/12/1 14:06 |
||||
* \* User: XianChaoWei |
||||
* \* Version: V1.0 |
||||
* \ |
||||
*/ |
||||
@Data |
||||
public class TokenDTO { |
||||
String tel; |
||||
Long timestamp; |
||||
String tokenType;//APP、PC
|
||||
} |
@ -0,0 +1,19 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
/** |
||||
* 钱包修改余额接口DTO |
||||
*/ |
||||
@Data |
||||
public class WalletChangeDTO { |
||||
String userId; |
||||
String recordId; // 记录标识
|
||||
String tokenName; // 币种名称
|
||||
BigDecimal freeBalance; // 可用余额
|
||||
BigDecimal freezeBalance; // 冻结余额
|
||||
BigDecimal gasBalance; // 手续费
|
||||
String walletType; // 钱包标识
|
||||
} |
@ -0,0 +1,18 @@ |
||||
package com.blockchain.common.base.dto; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.math.BigDecimal; |
||||
|
||||
/** |
||||
* 钱包修改余额接口DTO |
||||
*/ |
||||
@Data |
||||
public class WalletOrderDTO { |
||||
String userId; |
||||
String recordId; // 记录标识(可以为空)
|
||||
String tokenName; // 币种名称
|
||||
BigDecimal freeBalance; // 可用余额
|
||||
BigDecimal freezeBalance; // 冻结余额
|
||||
String walletType; // 钱包标识
|
||||
} |
@ -0,0 +1,10 @@ |
||||
package com.blockchain.common.base.entity; |
||||
|
||||
import java.io.Serializable; |
||||
|
||||
/** |
||||
* @author huangxl |
||||
* Created on 2018/11/25 |
||||
*/ |
||||
public class BaseModel implements Serializable { |
||||
} |
@ -0,0 +1,57 @@ |
||||
package com.blockchain.common.base.enums; |
||||
|
||||
public enum BaseResultEnums { |
||||
SUCCESS(200, "请求成功", "Request success", "請求成功"), |
||||
NO_LOGIN(201, "未登录", "No login", "未登錄"), |
||||
LOGIN_REPLACED(202, "您的账号在别处登录!", "Your account is logged in elsewhere!", "您的帳號在別處登錄"), |
||||
RSA_ERROR(250, "加密错误", "RSACoder error", "加密錯誤"), |
||||
BUSY(300, "服务器繁忙", "Server busy", "伺服器繁忙"), |
||||
DEFAULT(500, "系统错误", "System error", "系統錯誤"), |
||||
PASSWORD_ERROR(300, "密码错误", "Password error", "密碼錯誤"), |
||||
PARAMS_ERROR(403, "参数异常", "Params error", "參數異常"), |
||||
NOT_FOUND(404, "NOT FOUND", "Params error", "參數異常"); |
||||
|
||||
private int code; |
||||
private String hkmsg; |
||||
private String enMsg; |
||||
private String cnmsg; |
||||
|
||||
BaseResultEnums(int code, String cnmsg, String enMsg, String hkmsg) { |
||||
this.code = code; |
||||
this.cnmsg = cnmsg; |
||||
this.enMsg = enMsg; |
||||
this.hkmsg = hkmsg; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public void setCode(int code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public String getHkmsg() { |
||||
return hkmsg; |
||||
} |
||||
|
||||
public void setHkmsg(String hkmsg) { |
||||
this.hkmsg = hkmsg; |
||||
} |
||||
|
||||
public String getEnMsg() { |
||||
return enMsg; |
||||
} |
||||
|
||||
public void setEnMsg(String enMsg) { |
||||
this.enMsg = enMsg; |
||||
} |
||||
|
||||
public String getCnmsg() { |
||||
return cnmsg; |
||||
} |
||||
|
||||
public void setCnmsg(String cnmsg) { |
||||
this.cnmsg = cnmsg; |
||||
} |
||||
} |
@ -0,0 +1,94 @@ |
||||
package com.blockchain.common.base.enums; |
||||
|
||||
import lombok.Data; |
||||
|
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
|
||||
public enum PushEnums { |
||||
OTC_ORDER_DEAL_BUY("OTC_ORDER_DEAL_BUY", "法币交易", "已有用户下单向您购买代币,请尽快处理!", "Fiat", "There are already users under one-way you buy token, please deal with it as soon as possible!"), |
||||
OTC_ORDER_DEAL_SELL("OTC_ORDER_DEAL_SELL", "法币交易", "已有用户下单向您出售代币,请尽快处理!", "Fiat", "Existing users under one-way you sell tokens, please deal with as soon as possible!"), |
||||
OTC_ORDER_PAY("OTC_ORDER_PAY", "法币交易", "买家已确认付款请尽快处理!", "Fiat", "The buyer has confirmed the payment, please deal with it as soon as possible!"), |
||||
OTC_ORDER_RECEIPT("OTC_ORDER_RECEIPT", "法币交易", "卖家已确认收款,交易完成!", "Fiat", "The seller has confirmed the payment, the transaction is completed!"), |
||||
OTC_ORDER_APPEAL("OTC_ORDER_APPEAL", "法币交易", "订单已进入申诉流程,请尽快处理!", "Fiat", "The order has entered the complaint process, please deal with it as soon as possible!"), |
||||
OTC_ORDER_APPEAL_FINISH("OTC_ORDER_APPEAL_FINISH", "法币交易", "订单申诉已结束,请前往查看>>", "Fiat", "The appeal of order is over, please go to see >>"), |
||||
OTC_ORDER_CANCEL("OTC_ORDER_CANCEL", "法币交易", "订单已取消,买家已取消订单!", "Fiat", "Order cancelled, buyer cancelled order!"), |
||||
OTC_ORDER_AUTO_CANCEL("OTC_ORDER_AUTO_CANCEL", "法币交易", "买家付款超时,订单已自动取消!", "Fiat", "Buyer payment timeout, the order has been automatically cancelled!"), |
||||
OTC_AD_ADMIND_CANCEL("OTC_AD_ADMIND_CANCEL", "法币交易", "后台管理员已经您的广告取消,请前往查看>>", "Fiat", "Background administrator has cancelled your advertisement, please go to see >>"), |
||||
OTC_MARKET_AGREE("OTC_MARKET_AGREE", "焰火网", "您提交的市商申请已通过!", "FLAME", "Your marketing application has been approved!"), |
||||
OTC_MARKET_REJECT("OTC_MARKET_REJECT", "焰火网", "您提交的市商申请已被驳回!", "FLAME", "Your marketing application has been rejected!"), |
||||
OTC_MARKET_CANCEL_AGREE("OTC_MARKET_CANCEL_AGREE", "焰火网", "您提交的取消市商申请已通过!", "FLAME", "Your application for cancellation has been approved!"), |
||||
OTC_MARKET_CANCEL_REJECT("OTC_MARKET_CANCEL_REJECT", "焰火网", "您提交的取消市商申请已驳回!", "FLAME", "Your application for cancellation has been rejected!"), |
||||
|
||||
CCT_HISTORY_MARK("CCT_HISTORY_MARK", "币币交易", "您的订单已成交,请前往查看>>", "Exchange", "Your order has been completed, please go to >>"), |
||||
CCT_HISTORY_AUTO_CANCEL("CCT_HISTORY_AUTO_CANCEL", "币币交易", "找不到匹配的撮合订单,订单已自动撤销", "Exchange", "Matching matching order cannot be found, the order has been automatically cancelled"), |
||||
CCT_HISTORY_ADMIN_CANCEL("CCT_HISTORY_ADMIN_CANCEL", "币币交易", "后台管理员已将您的订单取消,请前往查看>>", "Exchange", "The background administrator has cancelled your order. Please check >>"), |
||||
; |
||||
|
||||
private String pushType; |
||||
private String cnTitle; |
||||
private String cnContent; |
||||
private String enTitle; |
||||
private String enContent; |
||||
|
||||
private static Map<String, PushEnums> enumsMap = new HashMap<>(); |
||||
|
||||
static { |
||||
PushEnums[] pushEnums = PushEnums.values(); |
||||
for (PushEnums pushEnum : pushEnums) { |
||||
enumsMap.put(pushEnum.getPushType(), pushEnum); |
||||
} |
||||
} |
||||
|
||||
public static PushEnums getEnumByPushType(String pushType) { |
||||
return enumsMap.get(pushType); |
||||
} |
||||
|
||||
PushEnums(String pushType, String cnTitle, String cnContent, String enTitle, String enContent) { |
||||
this.pushType = pushType; |
||||
this.cnTitle = cnTitle; |
||||
this.cnContent = cnContent; |
||||
this.enTitle = enTitle; |
||||
this.enContent = enContent; |
||||
} |
||||
|
||||
public String getPushType() { |
||||
return pushType; |
||||
} |
||||
|
||||
public void setPushType(String pushType) { |
||||
this.pushType = pushType; |
||||
} |
||||
|
||||
public String getCnTitle() { |
||||
return cnTitle; |
||||
} |
||||
|
||||
public void setCnTitle(String cnTitle) { |
||||
this.cnTitle = cnTitle; |
||||
} |
||||
|
||||
public String getCnContent() { |
||||
return cnContent; |
||||
} |
||||
|
||||
public void setCnContent(String cnContent) { |
||||
this.cnContent = cnContent; |
||||
} |
||||
|
||||
public String getEnTitle() { |
||||
return enTitle; |
||||
} |
||||
|
||||
public void setEnTitle(String enTitle) { |
||||
this.enTitle = enTitle; |
||||
} |
||||
|
||||
public String getEnContent() { |
||||
return enContent; |
||||
} |
||||
|
||||
public void setEnContent(String enContent) { |
||||
this.enContent = enContent; |
||||
} |
||||
} |
@ -0,0 +1,57 @@ |
||||
package com.blockchain.common.base.exception; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.util.HttpRequestUtil; |
||||
import lombok.Data; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
/** |
||||
* 自定义基础异常,用于向上跑出可预知异常 |
||||
* |
||||
* @author huangxl |
||||
* @create 2018-11-12 11:09 |
||||
*/ |
||||
@Data |
||||
public class BaseException extends RuntimeException { |
||||
protected int code; |
||||
protected String msg; |
||||
|
||||
public BaseException() { |
||||
this(BaseResultEnums.DEFAULT); |
||||
} |
||||
|
||||
public BaseException(int code, String msg) { |
||||
this.code = code; |
||||
this.msg = msg; |
||||
} |
||||
|
||||
public BaseException(BaseResultEnums rs) { |
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
||||
//可能是定时器调用,避免获取request空指针
|
||||
if (servletRequestAttributes == null) { |
||||
this.code = rs.getCode(); |
||||
this.msg = rs.getCnmsg(); |
||||
} else { |
||||
HttpServletRequest request = servletRequestAttributes.getRequest(); |
||||
String userLocale = HttpRequestUtil.getUserLocale(request); |
||||
String msg = ""; |
||||
switch (userLocale) { |
||||
case BaseConstant.USER_LOCALE_EN_US: |
||||
msg = rs.getEnMsg(); |
||||
break; |
||||
case BaseConstant.USER_LOCALE_ZH_HK: |
||||
msg = rs.getHkmsg(); |
||||
break; |
||||
default: |
||||
msg = rs.getCnmsg(); |
||||
break; |
||||
} |
||||
this.code = rs.getCode(); |
||||
this.msg = msg; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
package com.blockchain.common.base.exception; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
|
||||
/** |
||||
* @author huangxl |
||||
* @create 2018-11-21 21:19 |
||||
*/ |
||||
public class RPCException extends BaseException { |
||||
public RPCException(int code, String msg) { |
||||
super(code, msg); |
||||
} |
||||
public RPCException(ResultDTO rs) { |
||||
this.code = rs.getCode(); |
||||
this.msg = rs.getMsg(); |
||||
} |
||||
} |
@ -0,0 +1,757 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import org.apache.commons.lang3.ArrayUtils; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.math.BigInteger; |
||||
import java.math.MathContext; |
||||
import java.math.RoundingMode; |
||||
import java.text.ParseException; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Calendar; |
||||
import java.util.Date; |
||||
|
||||
public class DateTimeUtils { |
||||
/** |
||||
* 计算精度 |
||||
*/ |
||||
private static final MathContext mc = new MathContext(64, RoundingMode.HALF_UP); |
||||
|
||||
/* 毫秒级别常量 START */ |
||||
/** |
||||
* 一秒包含多少毫秒 |
||||
*/ |
||||
public static final Long MILLISECOND_OF_SECOND = 1000L; |
||||
|
||||
/** |
||||
* 一分钟包含多少毫秒 |
||||
*/ |
||||
public static final Long MILLISECOND_OF_MINUTE = 60 * MILLISECOND_OF_SECOND; |
||||
|
||||
/** |
||||
* 一小时包含多少毫秒 |
||||
*/ |
||||
public static final Long MILLISECOND_OF_HOUR = 60 * MILLISECOND_OF_MINUTE; |
||||
|
||||
/** |
||||
* 一日包含多少毫秒 |
||||
*/ |
||||
public static final Long MILLISECOND_OF_DAY = 24 * MILLISECOND_OF_HOUR; |
||||
|
||||
/** |
||||
* 一星期包含多少毫秒 |
||||
*/ |
||||
public static final Long MILLISECOND_OF_WEEK = 7 * MILLISECOND_OF_DAY; |
||||
|
||||
/* 毫秒级别常量 END */ |
||||
/* 支持的常用格式 START */ |
||||
/** |
||||
* 日期时间毫秒格式 |
||||
*/ |
||||
public static final String DATE_TIME_MILLISECOND_FORMAT = "yyyy-MM-dd HH:mm:ss SSS"; |
||||
|
||||
/** |
||||
* 日期时间格式 |
||||
*/ |
||||
public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; |
||||
|
||||
/** |
||||
* 日期小时格式 |
||||
*/ |
||||
public static final String DATE_HOUR_FORMAT = "yyyy-MM-dd HH"; |
||||
|
||||
/** |
||||
* 日期小时分钟格式 |
||||
*/ |
||||
public static final String DATE_HOUR_MINUTE_FORMAT = "yyyy-MM-dd HH:mm"; |
||||
|
||||
/** |
||||
* 日期格式 |
||||
*/ |
||||
public static final String YEAR_MONTH_DATE_FORMAT = "yyyy-MM-dd"; |
||||
|
||||
/** |
||||
* 年份月份格式 |
||||
*/ |
||||
public static final String YEAR_MONTH_FORMAT = "yyyy-MM"; |
||||
|
||||
/** |
||||
* 月日时 |
||||
*/ |
||||
public static final String MONTH_DAY_HOUR_FORMAT = "MM-dd HH"; |
||||
|
||||
|
||||
/** |
||||
* 月日 |
||||
*/ |
||||
public static final String MONTH_DAY_FORMAT = "MM-dd"; |
||||
|
||||
/** |
||||
* 时间格式 |
||||
*/ |
||||
public static final String TIME_FORMAT = "HH:mm:ss"; |
||||
|
||||
/** |
||||
* 小时分钟格式 |
||||
*/ |
||||
public static final String HOUR_MINUTE_FORMAT = "HH:mm"; |
||||
|
||||
/** |
||||
* 4位长度年格式 |
||||
*/ |
||||
public static final String YEAR_4_FORMAT = "yyyy"; |
||||
|
||||
/** |
||||
* 2位长度年格式 |
||||
*/ |
||||
public static final String YEAR_2_FORMAT = "yy"; |
||||
|
||||
/** |
||||
* 月格式 |
||||
*/ |
||||
public static final String MONTH_FORMAT = "MM"; |
||||
|
||||
/** |
||||
* 日格式 |
||||
*/ |
||||
public static final String DAY_FORMAT = "dd"; |
||||
|
||||
/** |
||||
* 24小时格式 |
||||
*/ |
||||
public static final String HOUR_24_FORMAT = "HH"; |
||||
|
||||
/** |
||||
* 12小时格式 |
||||
*/ |
||||
public static final String HOUR_12_FORMAT = "hh"; |
||||
|
||||
/** |
||||
* 分钟格式 |
||||
*/ |
||||
public static final String MINUTE_FORMAT = "mm"; |
||||
|
||||
/** |
||||
* 秒格式 |
||||
*/ |
||||
public static final String SECOND_FORMAT = "ss"; |
||||
|
||||
|
||||
/* 支持的常用格式 END */ |
||||
|
||||
/** |
||||
* 时间域枚举类 |
||||
*/ |
||||
public enum DateTimeField { |
||||
/** |
||||
* 年 |
||||
*/ |
||||
YEAR(1, Calendar.YEAR, "年"), |
||||
/** |
||||
* 月 |
||||
*/ |
||||
MONTH(2, Calendar.MONTH, "月"), |
||||
/** |
||||
* 周 |
||||
*/ |
||||
WEEK(4, Calendar.DAY_OF_WEEK, "周"), |
||||
/** |
||||
* 日 |
||||
*/ |
||||
DAY(8, Calendar.DATE, "日"), |
||||
/** |
||||
* 时 |
||||
*/ |
||||
HOUR(16, Calendar.HOUR_OF_DAY, "时"), |
||||
/** |
||||
* 分 |
||||
*/ |
||||
MINUTE(32, Calendar.MINUTE, "分"), |
||||
/** |
||||
* 秒 |
||||
*/ |
||||
SECOND(64, Calendar.SECOND, "秒"); |
||||
|
||||
private Integer key; |
||||
|
||||
private Integer calendarFieldVal; |
||||
|
||||
private String value; |
||||
|
||||
private DateTimeField() { |
||||
} |
||||
|
||||
private DateTimeField(Integer key, Integer calendarFieldVal, String value) { |
||||
this.key = key; |
||||
this.calendarFieldVal = calendarFieldVal; |
||||
this.value = value; |
||||
} |
||||
|
||||
public Integer getKey() { |
||||
return key; |
||||
} |
||||
|
||||
public void setKey(Integer key) { |
||||
this.key = key; |
||||
} |
||||
|
||||
public Integer getCalendarFieldVal() { |
||||
return calendarFieldVal; |
||||
} |
||||
|
||||
public void setCalendarFieldVal(Integer calendarFieldVal) { |
||||
this.calendarFieldVal = calendarFieldVal; |
||||
} |
||||
|
||||
public String getValue() { |
||||
return value; |
||||
} |
||||
|
||||
public void setValue(String value) { |
||||
this.value = value; |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return this.key + "-" + calendarFieldVal + "-" + this.value; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 不支持时间域类型操作异常 |
||||
*/ |
||||
public static class NoSupportDateTimeFieldException extends RuntimeException { |
||||
|
||||
private static final long serialVersionUID = 1189120547395966542L; |
||||
|
||||
public NoSupportDateTimeFieldException() { |
||||
super(); |
||||
} |
||||
|
||||
public NoSupportDateTimeFieldException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { |
||||
super(message, cause, enableSuppression, writableStackTrace); |
||||
} |
||||
|
||||
public NoSupportDateTimeFieldException(String message, Throwable cause) { |
||||
super(message, cause); |
||||
} |
||||
|
||||
public NoSupportDateTimeFieldException(String message) { |
||||
super(message); |
||||
} |
||||
|
||||
public NoSupportDateTimeFieldException(Throwable cause) { |
||||
super(cause); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将毫秒格式化成指定格式的字符串 |
||||
* |
||||
* @param date 长整型的毫秒 |
||||
* @param formatStr 格式字符串 |
||||
* @return 返回已经转换成指定格式的字符串 |
||||
*/ |
||||
public static String format(Long date, String formatStr) { |
||||
Calendar calendar = Calendar.getInstance(); |
||||
calendar.setTimeInMillis(date); |
||||
return format(calendar.getTime(), formatStr); |
||||
} |
||||
|
||||
/** |
||||
* 将Calendar时间格式化成默认格式的字符串 |
||||
* |
||||
* @param date Calendar时间 |
||||
* @return 返回已经转换成指定格式的字符串 |
||||
*/ |
||||
public static String format(Calendar date) { |
||||
return format(date.getTime()); |
||||
} |
||||
|
||||
/** |
||||
* 将Date时间格式化成默认格式的字符串 |
||||
* |
||||
* @param date Date时间 |
||||
* @return 返回已经转换成指定格式的字符串 |
||||
*/ |
||||
public static String format(Date date) { |
||||
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT); |
||||
return sdf.format(date); |
||||
} |
||||
|
||||
/** |
||||
* 将Calendar时间格式化成指定格式的字符串 |
||||
* |
||||
* @param date Calendar时间 |
||||
* @param formatStr 格式字符串 |
||||
* @return 返回已经转换成指定格式的字符串 |
||||
*/ |
||||
public static String format(Calendar date, String formatStr) { |
||||
return format(date.getTime(), formatStr); |
||||
} |
||||
|
||||
/** |
||||
* 将Date时间格式化成指定格式的字符串 |
||||
* |
||||
* @param date Date时间 |
||||
* @param formatStr 格式字符串 |
||||
* @return 返回已经转换成指定格式的字符串 |
||||
*/ |
||||
public static String format(Date date, String formatStr) { |
||||
SimpleDateFormat sdf = new SimpleDateFormat(formatStr); |
||||
return sdf.format(date); |
||||
} |
||||
|
||||
/** |
||||
* 将指定的日期字符串按照默认格式转化成Date对象 |
||||
* |
||||
* @param dateStr 日期字符串 |
||||
* @return 转化后的Date对象 |
||||
*/ |
||||
public static Date parse(String dateStr) { |
||||
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT); |
||||
try { |
||||
return sdf.parse(dateStr); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将指定的日期字符串按照默认格式转化成Date对象 |
||||
* |
||||
* @param dateStr 日期字符串 |
||||
* @param formatStr 格式字符串 |
||||
* @return 转化后的Date对象 |
||||
*/ |
||||
public static Date parse(String dateStr, String formatStr) { |
||||
SimpleDateFormat sdf = new SimpleDateFormat(formatStr); |
||||
try { |
||||
return sdf.parse(dateStr); |
||||
} catch (ParseException e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 将指定的日期字符串按照多个格式转化成Date对象 |
||||
* |
||||
* @param dateStr 日期字符串 |
||||
* @param formats 格式字符串,自动匹配适合的格式 |
||||
* @return 转化后的Date对象 |
||||
*/ |
||||
public static Date parse(String dateStr, String[] formats) { |
||||
if (ArrayUtils.isNotEmpty(formats)) { |
||||
for (int i = 0, len = formats.length; i < len; i++) { |
||||
String format = formats[i]; |
||||
Date parseDate = parse(dateStr, format); |
||||
if (null != parseDate) { |
||||
return parseDate; |
||||
} |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 将指定的Date对象按照默认格式重新转化成新的Date对象,这个目的是为了排除其他时间域的干扰,比如:排除毫秒、秒等干扰,特殊情况下还可以排除日、月等干扰 |
||||
* |
||||
* @param date 指定的Date对象 |
||||
* @return 新的Date对象 |
||||
*/ |
||||
public static Date parse(Date date) { |
||||
String dateFormatStr = format(date); |
||||
return parse(dateFormatStr); |
||||
} |
||||
|
||||
/** |
||||
* 将指定的Date对象按照指定的格式重新转化成新的Date对象,这个目的是为了排除其他时间域的干扰,比如:排除毫秒、秒等干扰,特殊情况下还可以排除日、月等干扰 |
||||
* |
||||
* @param date 指定的Date对象 |
||||
* @param formatStr 格式字符串 |
||||
* @return 新的Date对象 |
||||
*/ |
||||
public static Date parse(Date date, String formatStr) { |
||||
String dateFormatStr = format(date, formatStr); |
||||
return parse(dateFormatStr, formatStr); |
||||
} |
||||
|
||||
/** |
||||
* 将指定的Calendar对象按照指定的格式重新转化成新的Date对象,这个目的是为了排除其他时间域的干扰,比如:排除毫秒、秒等干扰,特殊情况下还可以排除日、月等干扰 |
||||
* |
||||
* @param date 指定的Calendar对象 |
||||
* @param formatStr 格式字符串 |
||||
* @return 新的Date对象 |
||||
*/ |
||||
public static Date parse(Calendar date, String formatStr) { |
||||
return parse(date.getTime(), formatStr); |
||||
} |
||||
|
||||
/** |
||||
* 将指定的毫秒按照指定的格式重新转化成新的Date对象,这个目的是为了排除其他时间域的干扰,比如:排除毫秒、秒等干扰,特殊情况下还可以排除日、月等干扰 |
||||
* |
||||
* @param date 指定的毫秒 |
||||
* @param formatStr 格式字符串 |
||||
* @return 新的Date对象 |
||||
*/ |
||||
public static Date parse(Long date, String formatStr) { |
||||
Calendar calendar = Calendar.getInstance(); |
||||
calendar.setTimeInMillis(date); |
||||
return parse(calendar, formatStr); |
||||
} |
||||
|
||||
/** |
||||
* 获取开始时间 |
||||
* |
||||
* @param field 指定的时间域 |
||||
* @param date 指定的日期 |
||||
* @return 获取指定字段开始的时间(精确级别到毫秒) |
||||
*/ |
||||
public static Date getStart(DateTimeField field, Date date) { |
||||
Calendar calendar = Calendar.getInstance(); |
||||
calendar.setTime(date); |
||||
switch (field) { |
||||
case YEAR: |
||||
calendar.set(Calendar.MONTH, calendar.getActualMinimum(Calendar.MONTH)); |
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH)); |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
case MONTH: |
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH)); |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
case WEEK: |
||||
calendar.set(Calendar.DAY_OF_WEEK, calendar.getActualMinimum(Calendar.DAY_OF_WEEK)); |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
case DAY: |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMinimum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
case HOUR: |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMinimum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
case MINUTE: |
||||
calendar.set(Calendar.SECOND, calendar.getActualMinimum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
case SECOND: |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMinimum(Calendar.MILLISECOND)); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
return calendar.getTime(); |
||||
} |
||||
|
||||
/** |
||||
* 获取结束时间 |
||||
* |
||||
* @param field 指定的域 |
||||
* @param date 指定的日期 |
||||
* @return 获取指定字段结束的时间(精确级别到秒) |
||||
*/ |
||||
public static Date getEnd(DateTimeField field, Date date) { |
||||
Calendar calendar = Calendar.getInstance(); |
||||
calendar.setTime(date); |
||||
switch (field) { |
||||
case YEAR: |
||||
calendar.set(Calendar.MONTH, calendar.getActualMaximum(Calendar.MONTH)); |
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
case MONTH: |
||||
calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
case WEEK: |
||||
calendar.set(Calendar.DAY_OF_WEEK, calendar.getActualMaximum(Calendar.DAY_OF_WEEK)); |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
case DAY: |
||||
calendar.set(Calendar.HOUR_OF_DAY, calendar.getActualMaximum(Calendar.HOUR_OF_DAY)); |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
case HOUR: |
||||
calendar.set(Calendar.MINUTE, calendar.getActualMaximum(Calendar.MINUTE)); |
||||
calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
case MINUTE: |
||||
calendar.set(Calendar.SECOND, calendar.getActualMaximum(Calendar.SECOND)); |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
case SECOND: |
||||
calendar.set(Calendar.MILLISECOND, calendar.getActualMaximum(Calendar.MILLISECOND)); |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
return calendar.getTime(); |
||||
} |
||||
|
||||
/** |
||||
* 判断指定的多个Calendar对象是否在同一个时间域内,比如:日、月、年、时、分等等 |
||||
* |
||||
* @param field 指定的时间域,日、月、年、时、分等等 |
||||
* @param dates 指定的多个Calendar对象 |
||||
* @return 是否在同一个时间与内, true/false |
||||
*/ |
||||
public static Boolean same(DateTimeField field, Calendar dates[]) { |
||||
if (ArrayUtils.isNotEmpty(dates) && 1 < dates.length) { |
||||
for (int i = 1, len = dates.length; i < len; i++) { |
||||
Calendar std = dates[0];// 第一个作为标准比较
|
||||
Calendar target = dates[i]; |
||||
Boolean sameFlag = same(field, std, target); |
||||
if (sameFlag) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} else { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断指定的多个Date对象是否在同一个时间域内,比如:日、月、年、时、分等等 |
||||
* |
||||
* @param field 指定的时间域,日、月、年、时、分等等 |
||||
* @param dates 指定的多个Date对象 |
||||
* @return 是否在同一个时间与内, true/false |
||||
*/ |
||||
public static Boolean same(DateTimeField field, Date dates[]) { |
||||
if (ArrayUtils.isNotEmpty(dates) && 1 < dates.length) { |
||||
Calendar[] parseCalendars = new Calendar[dates.length]; |
||||
for (int i = 0, len = dates.length; i < len; i++) { |
||||
Date date = dates[i]; |
||||
Calendar calendar = Calendar.getInstance(); |
||||
calendar.setTime(date); |
||||
parseCalendars[i] = calendar; |
||||
} |
||||
return same(field, parseCalendars); |
||||
} else { |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断指定的两个Date对象是否在同一个时间域内,比如:日、月、年、时、分等等 |
||||
* |
||||
* @param field 指定的时间域,日、月、年、时、分等等 |
||||
* @param first 第一个Date对象 |
||||
* @param second 第二个Date对象 |
||||
* @return 是否在同一个时间与内, true/false |
||||
*/ |
||||
public static Boolean same(DateTimeField field, Date first, Date second) { |
||||
Calendar startCalendar = Calendar.getInstance(); |
||||
startCalendar.setTime(first); |
||||
Calendar endCalendar = Calendar.getInstance(); |
||||
endCalendar.setTime(second); |
||||
return same(field, startCalendar, endCalendar); |
||||
} |
||||
|
||||
/** |
||||
* 判断指定的两个Calendar对象是否在同一个时间域内,比如:日、月、年、时、分等等 |
||||
* |
||||
* @param field 指定的时间域,日、月、年、时、分等等 |
||||
* @param first 第一个Calendar对象 |
||||
* @param second 第二个Calendar对象 |
||||
* @return 是否在同一个时间与内, true/false |
||||
*/ |
||||
public static Boolean same(DateTimeField field, Calendar first, Calendar second) { |
||||
Date parseFirstDate = null; |
||||
Date parseSecondDate = null; |
||||
switch (field) { |
||||
case YEAR: |
||||
parseFirstDate = parse(first, YEAR_4_FORMAT); |
||||
parseSecondDate = parse(second, YEAR_4_FORMAT); |
||||
break; |
||||
case MONTH: |
||||
parseFirstDate = parse(first, YEAR_MONTH_FORMAT); |
||||
parseSecondDate = parse(second, YEAR_MONTH_FORMAT); |
||||
break; |
||||
case WEEK: |
||||
Calendar firstCalendar = Calendar.getInstance(); |
||||
Calendar secondCalendar = Calendar.getInstance(); |
||||
Date parseFirstCalendarDate = parse(first, YEAR_MONTH_DATE_FORMAT); |
||||
Date parseSecondCalendarDate = parse(second, YEAR_MONTH_DATE_FORMAT); |
||||
firstCalendar.setTime(parseFirstCalendarDate); |
||||
secondCalendar.setTime(parseSecondCalendarDate); |
||||
firstCalendar.set(Calendar.DAY_OF_WEEK, firstCalendar.getActualMinimum(Calendar.DAY_OF_WEEK)); |
||||
secondCalendar.set(Calendar.DAY_OF_WEEK, firstCalendar.getActualMinimum(Calendar.DAY_OF_WEEK)); |
||||
parseFirstDate = firstCalendar.getTime(); |
||||
parseSecondDate = secondCalendar.getTime(); |
||||
break; |
||||
case DAY: |
||||
parseFirstDate = parse(first, YEAR_MONTH_DATE_FORMAT); |
||||
parseSecondDate = parse(second, YEAR_MONTH_DATE_FORMAT); |
||||
break; |
||||
case HOUR: |
||||
parseFirstDate = parse(first, DATE_HOUR_FORMAT); |
||||
parseSecondDate = parse(second, DATE_HOUR_FORMAT); |
||||
break; |
||||
case MINUTE: |
||||
parseFirstDate = parse(first, DATE_HOUR_MINUTE_FORMAT); |
||||
parseSecondDate = parse(second, DATE_HOUR_MINUTE_FORMAT); |
||||
break; |
||||
case SECOND: |
||||
parseFirstDate = parse(first, DATE_TIME_FORMAT); |
||||
parseSecondDate = parse(second, DATE_TIME_FORMAT); |
||||
break; |
||||
default: |
||||
parseFirstDate = parse(first, DATE_TIME_MILLISECOND_FORMAT); |
||||
parseSecondDate = parse(second, DATE_TIME_MILLISECOND_FORMAT); |
||||
break; |
||||
} |
||||
return (parseFirstDate.getTime() == parseSecondDate.getTime()); |
||||
} |
||||
|
||||
/** |
||||
* 获取两个Data对象的时间差,并且按照指定的时间域为标准来计算 |
||||
* |
||||
* @param field 指定的时间域,日、月、年、时、分等等 |
||||
* @param start 第一个Date对象 |
||||
* @param end 第二个Date对象 |
||||
* @param ignoreMilliSecond 是否忽略毫秒的干扰 |
||||
* @return 指定的时间差, 根据field的域来返回指定时间差 |
||||
*/ |
||||
public static BigDecimal difference(DateTimeField field, Date start, Date end, boolean ignoreMilliSecond) { |
||||
Calendar startCalendar = Calendar.getInstance(); |
||||
startCalendar.setTime(start); |
||||
Calendar endCalendar = Calendar.getInstance(); |
||||
endCalendar.setTime(end); |
||||
return difference(field, startCalendar, endCalendar, ignoreMilliSecond); |
||||
} |
||||
|
||||
/** |
||||
* 获取两个Calendar对象的时间差,并且按照指定的时间域为标准来计算 |
||||
* |
||||
* @param field 指定的时间域,日、月、年、时、分等等 |
||||
* @param start 第一个Calendar对象 |
||||
* @param end 第二个Calendar对象 |
||||
* @param ignoreMilliSecond 是否忽略毫秒的干扰 |
||||
* @return 指定的时间差, 根据field的域来返回指定时间差 |
||||
*/ |
||||
public static BigDecimal difference(DateTimeField field, Calendar start, Calendar end, boolean ignoreMilliSecond) { |
||||
BigDecimal returnVal = null; |
||||
switch (field) { |
||||
case YEAR: |
||||
case MONTH: |
||||
throw new NoSupportDateTimeFieldException("不支持YEAR/MONTH级别的时间差运算,因为标注参考时间不确定!"); |
||||
case WEEK: |
||||
returnVal = (new BigDecimal(difference(start, end, ignoreMilliSecond)).divide(BigDecimal.valueOf(MILLISECOND_OF_WEEK), mc).setScale(4, RoundingMode.HALF_UP)); |
||||
break; |
||||
case DAY: |
||||
returnVal = (new BigDecimal(difference(start, end, ignoreMilliSecond)).divide(BigDecimal.valueOf(MILLISECOND_OF_DAY), mc).setScale(4, RoundingMode.HALF_UP)); |
||||
break; |
||||
case HOUR: |
||||
returnVal = (new BigDecimal(difference(start, end, ignoreMilliSecond)).divide(BigDecimal.valueOf(MILLISECOND_OF_HOUR), mc).setScale(4, RoundingMode.HALF_UP)); |
||||
break; |
||||
case MINUTE: |
||||
returnVal = (new BigDecimal(difference(start, end, ignoreMilliSecond)).divide(BigDecimal.valueOf(MILLISECOND_OF_MINUTE), mc).setScale(4, RoundingMode.HALF_UP)); |
||||
break; |
||||
case SECOND: |
||||
returnVal = (new BigDecimal(difference(start, end, ignoreMilliSecond)).divide(BigDecimal.valueOf(MILLISECOND_OF_SECOND), mc).setScale(4, RoundingMode.HALF_UP)); |
||||
break; |
||||
default: |
||||
returnVal = new BigDecimal(difference(start, end, ignoreMilliSecond)); |
||||
break; |
||||
} |
||||
return returnVal; |
||||
} |
||||
|
||||
/** |
||||
* 获取两个Calendar对象的时间差,并且按照毫秒为标准来计算 |
||||
* |
||||
* @param start 第一个Calendar对象 |
||||
* @param end 第二个Calendar对象 |
||||
* @param ignoreMilliSecond 是否忽略毫秒的干扰 |
||||
* @return 指定的时间差, 根据field的域来返回指定时间差 |
||||
*/ |
||||
public static BigInteger difference(Calendar start, Calendar end, boolean ignoreMilliSecond) { |
||||
if (ignoreMilliSecond) { |
||||
start.clear(Calendar.MILLISECOND); |
||||
end.clear(Calendar.MILLISECOND); |
||||
} |
||||
BigInteger startMilliSecond = BigInteger.valueOf(start.getTimeInMillis()); |
||||
BigInteger endMilliSecond = BigInteger.valueOf(end.getTimeInMillis()); |
||||
return (endMilliSecond.subtract(startMilliSecond)); |
||||
} |
||||
|
||||
/** |
||||
* 获取两个Date对象的时间差,并且按照毫秒为标准来计算 |
||||
* |
||||
* @param start 第一个Date对象 |
||||
* @param end 第二个Date对象 |
||||
* @param ignoreMilliSecond 是否忽略毫秒的干扰 |
||||
* @return 指定的时间差, 根据field的域来返回指定时间差 |
||||
*/ |
||||
public static BigInteger difference(Date start, Date end, boolean ignoreMilliSecond) { |
||||
Calendar startCalendar = Calendar.getInstance(); |
||||
startCalendar.setTime(start); |
||||
Calendar endCalendar = Calendar.getInstance(); |
||||
endCalendar.setTime(end); |
||||
return difference(startCalendar, endCalendar, ignoreMilliSecond); |
||||
} |
||||
|
||||
/** |
||||
* 将时间毫秒数转化为时间间隔 |
||||
* |
||||
* @param timeMillis 间隔时间 |
||||
*/ |
||||
public static String getIntervalTimeInString(long timeMillis) { |
||||
long time = timeMillis; |
||||
long ts = 1000L;//1秒
|
||||
long tm = 1000L * 60;//一分钟
|
||||
long th = 1000L * 60 * 60;//一小时
|
||||
long td = 1000L * 60 * 60 * 24;//一天
|
||||
long tM = 1000L * 60 * 60 * 24 * 30;//一个月
|
||||
long ty = 1000L * 60 * 60 * 24 * 365;//一年
|
||||
if (time > ty) { |
||||
return time / ty + "年前"; |
||||
} |
||||
if (time > tM) { |
||||
return time / tM + "个月前"; |
||||
} |
||||
if (time > td) { |
||||
return time / td + "天前"; |
||||
} |
||||
if (time > th) { |
||||
return time / th + "小时前"; |
||||
} |
||||
if (time > tm) { |
||||
return time / tm + "分钟前"; |
||||
} |
||||
if (time > ts) { |
||||
return time / ts + "秒前"; |
||||
} |
||||
return "刚刚"; |
||||
} |
||||
} |
@ -0,0 +1,79 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.util.Collection; |
||||
|
||||
public class ExceptionPreconditionUtils { |
||||
/** |
||||
* 用于判断参数是否符合条件 |
||||
* |
||||
* @param flag 判断的条件 |
||||
* @param e 如果对象不符合条件,平台需要返回的业务错误 |
||||
*/ |
||||
public static void checkBool(boolean flag, BaseException e) { |
||||
if (!flag) { |
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断字符串不为空或空串 |
||||
* |
||||
* @param checkString 需要判断的字符串 |
||||
* @param e 返回的业务错误 |
||||
*/ |
||||
public static void checkStringNotBlank(String checkString, BaseException e) { |
||||
if (StringUtils.isBlank(checkString)) { |
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断一个集合是否为空(包含null和size为0的情况) |
||||
* |
||||
* @param collection |
||||
* @param e |
||||
*/ |
||||
public static void checkCollectionNotEmpty(Collection collection, BaseException e) { |
||||
if (collection == null || collection.size() == 0) { |
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断一个对象不可以为空 |
||||
* |
||||
* @param obj 需要判断的对象 |
||||
* @param e 如果对象为空,平台需要返回的业务错误代码 |
||||
*/ |
||||
public static void checkNotNull(Object obj, BaseException e) { |
||||
if (obj == null) { |
||||
throw e; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 检验参数不能为空 |
||||
* |
||||
* @param args 多个参数 |
||||
*/ |
||||
public static void notEmpty(Object... args) { |
||||
if (args == null) { |
||||
throw new BaseException(BaseResultEnums.PARAMS_ERROR); |
||||
} |
||||
for (Object obj : args) { |
||||
if (obj instanceof String) { |
||||
if (StringUtils.isEmpty((String) obj)) { |
||||
throw new BaseException(BaseResultEnums.PARAMS_ERROR); |
||||
} |
||||
} |
||||
if (obj == null) { |
||||
throw new BaseException(BaseResultEnums.PARAMS_ERROR); |
||||
} |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,138 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import org.apache.commons.lang3.RandomStringUtils; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
import org.springframework.web.multipart.MultipartFile; |
||||
import sun.misc.BASE64Decoder; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.io.File; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
import java.io.OutputStream; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Date; |
||||
|
||||
public class FileUploadHelper { |
||||
/** |
||||
* 保存文件 |
||||
* |
||||
* @param file 文件 |
||||
* @param relativeDir 文件类型 |
||||
* @throws IOException 存储异常 |
||||
*/ |
||||
protected static String saveFile(MultipartFile file, String rootDir, String relativeDir) throws IOException { |
||||
//源文件名
|
||||
String name = file.getOriginalFilename(); |
||||
//文件后缀名
|
||||
String suffix = name.substring(name.lastIndexOf(".")); |
||||
//格式化文件路径
|
||||
rootDir = formatSeparator(rootDir); |
||||
relativeDir = formatSeparator(relativeDir); |
||||
//申诉文件保存到本地/服务器
|
||||
String fileRelativePath = generateRelativePath(rootDir, relativeDir, suffix); |
||||
file.transferTo(new File(rootDir + fileRelativePath)); |
||||
return fileRelativePath; |
||||
} |
||||
|
||||
/** |
||||
* 将base64字符串存储为jpg文件 |
||||
* |
||||
* @param imgBase64 base64字符串 |
||||
* @param relativeDir 文件相对路径 |
||||
* @return 文件名 |
||||
* @throws Exception 存储异常 |
||||
*/ |
||||
protected static String generateImage(String imgBase64, String rootDir, String relativeDir) throws IOException { //对字节数组字符串进行Base64解码并生成图片
|
||||
if (StringUtils.isEmpty(imgBase64)) { |
||||
throw new RuntimeException("file base64 string is empty"); |
||||
} |
||||
BASE64Decoder decoder = new BASE64Decoder(); |
||||
//Base64解码
|
||||
byte[] b = decoder.decodeBuffer(imgBase64); |
||||
for (int i = 0; i < b.length; ++i) { |
||||
if (b[i] < 0) {//调整异常数据
|
||||
b[i] += 256; |
||||
} |
||||
} |
||||
//格式化文件路径
|
||||
rootDir = formatSeparator(rootDir); |
||||
relativeDir = formatSeparator(relativeDir); |
||||
//文件存放路径
|
||||
String relativePath = generateRelativePath(rootDir, relativeDir, ".jpg"); |
||||
OutputStream out = null; |
||||
try { |
||||
out = new FileOutputStream(rootDir + relativePath); |
||||
out.write(b); |
||||
out.flush(); |
||||
return relativePath; |
||||
} catch (IOException e) { |
||||
throw e; |
||||
} finally { |
||||
if (out != null) { |
||||
try { |
||||
out.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 文件名命名规则 |
||||
* |
||||
* @return 文件名 |
||||
*/ |
||||
private static String createFileName() { |
||||
String timeFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date()) + |
||||
RandomStringUtils.random(6, true, true); |
||||
return timeFormat; |
||||
} |
||||
|
||||
/** |
||||
* 生成文件所在目录,并返回文件的相对地址 |
||||
* |
||||
* @param rootPath 文件根目录 |
||||
* @param relativeDir 文件相对目录 |
||||
* @param suffix 文件后缀名 |
||||
* @return 文件相对地址 |
||||
*/ |
||||
private static String generateRelativePath(String rootPath, String relativeDir, String suffix) { |
||||
String separator = File.separator; |
||||
if (relativeDir.startsWith(separator)) { |
||||
relativeDir = relativeDir.substring(1); |
||||
} |
||||
//格式化后缀
|
||||
if (!suffix.startsWith(".")) { |
||||
suffix = "." + suffix; |
||||
} |
||||
String fileDir = rootPath + relativeDir; |
||||
File file = new File(fileDir); |
||||
if (!file.exists()) { |
||||
file.mkdirs(); |
||||
} |
||||
return relativeDir + createFileName() + suffix; |
||||
} |
||||
|
||||
/** |
||||
* 格式化文件分隔符 |
||||
* |
||||
* @param dir 目录 |
||||
* @return 格式化后的目录名 |
||||
*/ |
||||
private static String formatSeparator(String dir) { |
||||
String separator = File.separator; |
||||
if (StringUtils.isNotEmpty(dir)) { |
||||
String replace = separator.equals("\\") ? "\\\\" : "/"; |
||||
String format = dir.replaceAll("[\\\\/]+", replace); |
||||
if (!format.endsWith(separator)) { |
||||
format += separator; |
||||
} |
||||
return format; |
||||
} |
||||
return ""; |
||||
} |
||||
} |
@ -0,0 +1,74 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.dto.SessionUserDTO; |
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
/** |
||||
* 获取session用户信息的工具类 |
||||
*/ |
||||
public class HttpRequestUtil { |
||||
/** |
||||
* 获取用户国际化标识 |
||||
*/ |
||||
public static String getUserLocale(HttpServletRequest request) { |
||||
String userLocale = request.getParameter(BaseConstant.PARAMS_LOCALE); |
||||
if (StringUtils.isNotEmpty(userLocale)) { |
||||
return userLocale; |
||||
} |
||||
userLocale = request.getHeader(BaseConstant.PARAMS_LOCALE); |
||||
if(StringUtils.isNotEmpty(userLocale)){ |
||||
return userLocale; |
||||
} |
||||
return BaseConstant.USER_LOCALE_DEFAULT; |
||||
} |
||||
|
||||
/** |
||||
* 获取用户真实IP地址,不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址, |
||||
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值 |
||||
* |
||||
* @return ip |
||||
*/ |
||||
public static String getIpAddr() { |
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
||||
String ip = request.getHeader("x-forwarded-for"); |
||||
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) { |
||||
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
|
||||
if (ip.indexOf(",") != -1) { |
||||
ip = ip.split(",")[0]; |
||||
} |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("Proxy-Client-IP"); |
||||
System.out.println("Proxy-Client-IP ip: " + ip); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("WL-Proxy-Client-IP"); |
||||
System.out.println("WL-Proxy-Client-IP ip: " + ip); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("HTTP_CLIENT_IP"); |
||||
System.out.println("HTTP_CLIENT_IP ip: " + ip); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR"); |
||||
System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getHeader("X-Real-IP"); |
||||
System.out.println("X-Real-IP ip: " + ip); |
||||
} |
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { |
||||
ip = request.getRemoteAddr(); |
||||
System.out.println("getRemoteAddr ip: " + ip); |
||||
} |
||||
return ip == null ? "unknown" : ip; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,160 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import org.apache.commons.io.IOUtils; |
||||
import org.apache.http.Consts; |
||||
import org.apache.http.HttpEntity; |
||||
import org.apache.http.HttpResponse; |
||||
import org.apache.http.NameValuePair; |
||||
import org.apache.http.client.HttpClient; |
||||
import org.apache.http.client.config.RequestConfig; |
||||
import org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
import org.apache.http.client.methods.HttpGet; |
||||
import org.apache.http.client.methods.HttpPost; |
||||
import org.apache.http.client.methods.HttpRequestBase; |
||||
import org.apache.http.conn.ConnectionKeepAliveStrategy; |
||||
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; |
||||
import org.apache.http.impl.client.HttpClients; |
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
import org.apache.http.message.BasicNameValuePair; |
||||
import org.apache.http.protocol.HttpContext; |
||||
|
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.util.ArrayList; |
||||
import java.util.LinkedList; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
public class HttpUtilManager { |
||||
|
||||
private static HttpClient client; |
||||
private static long startTime = System.currentTimeMillis(); |
||||
public static PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(); |
||||
private static ConnectionKeepAliveStrategy keepAliveStrat = new DefaultConnectionKeepAliveStrategy() { |
||||
public long getKeepAliveDuration( |
||||
HttpResponse response, |
||||
HttpContext context) { |
||||
long keepAlive = super.getKeepAliveDuration(response, context); |
||||
|
||||
if (keepAlive == -1) { |
||||
keepAlive = 5000; |
||||
} |
||||
return keepAlive; |
||||
} |
||||
|
||||
}; |
||||
|
||||
private HttpUtilManager() { |
||||
client = HttpClients.custom().setConnectionManager(cm).setKeepAliveStrategy(keepAliveStrat).build(); |
||||
} |
||||
|
||||
public static void IdleConnectionMonitor() { |
||||
|
||||
if (System.currentTimeMillis() - startTime > 30000) { |
||||
startTime = System.currentTimeMillis(); |
||||
cm.closeExpiredConnections(); |
||||
cm.closeIdleConnections(30, TimeUnit.SECONDS); |
||||
} |
||||
} |
||||
|
||||
private static RequestConfig requestConfig = RequestConfig.custom() |
||||
.setSocketTimeout(20000) |
||||
.setConnectTimeout(20000) |
||||
.setConnectionRequestTimeout(20000) |
||||
.build(); |
||||
|
||||
|
||||
public static HttpUtilManager getInstance() { |
||||
return new HttpUtilManager(); |
||||
} |
||||
|
||||
public HttpClient getHttpClient() { |
||||
return client; |
||||
} |
||||
|
||||
private HttpPost httpPostMethod(String url) { |
||||
return new HttpPost(url); |
||||
} |
||||
|
||||
private HttpRequestBase httpGetMethod(String url) { |
||||
return new HttpGet(url); |
||||
} |
||||
|
||||
public String requestHttpGet(String url){ |
||||
return this.requestHttpGet(url,null); |
||||
} |
||||
|
||||
public String requestHttpGet(String url, String param){ |
||||
InputStream is = null; |
||||
String responseData = ""; |
||||
try { |
||||
IdleConnectionMonitor(); |
||||
if (param != null && !param.equals("")) { |
||||
if (url.endsWith("?")) { |
||||
url = url + param; |
||||
} else { |
||||
url = url + "?" + param; |
||||
} |
||||
} |
||||
HttpRequestBase method = this.httpGetMethod(url); |
||||
method.setConfig(requestConfig); |
||||
HttpResponse response = client.execute(method); |
||||
HttpEntity entity = response.getEntity(); |
||||
if (entity == null) { |
||||
return ""; |
||||
} |
||||
is = entity.getContent(); |
||||
responseData = IOUtils.toString(is, "UTF-8"); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
}finally { |
||||
if (is != null) { |
||||
try { |
||||
is.close(); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
} |
||||
} |
||||
return responseData; |
||||
} |
||||
|
||||
public String requestHttpPost(String url, Map<String, String> params) throws IOException { |
||||
InputStream is = null; |
||||
String responseData = ""; |
||||
IdleConnectionMonitor(); |
||||
|
||||
HttpPost method = this.httpPostMethod(url); |
||||
List<NameValuePair> valuePairs = this.convertMap2PostParams(params); |
||||
|
||||
UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(valuePairs, Consts.UTF_8); |
||||
method.setEntity(urlEncodedFormEntity); |
||||
method.setConfig(requestConfig); |
||||
HttpResponse response = client.execute(method); |
||||
HttpEntity entity = response.getEntity(); |
||||
if (entity == null) { |
||||
return ""; |
||||
} |
||||
is = entity.getContent(); |
||||
responseData = IOUtils.toString(is, "UTF-8"); |
||||
return responseData; |
||||
|
||||
} |
||||
|
||||
private List<NameValuePair> convertMap2PostParams(Map<String, String> params) { |
||||
List<String> keys = new ArrayList<String>(params.keySet()); |
||||
if (keys.isEmpty()) { |
||||
return null; |
||||
} |
||||
int keySize = keys.size(); |
||||
List<NameValuePair> data = new LinkedList<NameValuePair>(); |
||||
for (int i = 0; i < keySize; i++) { |
||||
String key = keys.get(i); |
||||
String value = params.get(key); |
||||
data.add(new BasicNameValuePair(key, value)); |
||||
} |
||||
return data; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,273 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
import com.fasterxml.jackson.databind.JavaType; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy; |
||||
|
||||
import java.io.IOException; |
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Method; |
||||
import java.math.BigDecimal; |
||||
import java.text.SimpleDateFormat; |
||||
import java.util.*; |
||||
|
||||
public class JsonUtils { |
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper(); |
||||
|
||||
/** |
||||
* 将对象转换成json字符串。 |
||||
* |
||||
* @param data |
||||
* @return |
||||
*/ |
||||
public static String objectToJson(Object data) { |
||||
try { |
||||
String string = MAPPER.writeValueAsString(data); |
||||
return string; |
||||
} catch (JsonProcessingException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 将json结果集转化为对象 |
||||
* |
||||
* @param jsonData json数据 |
||||
* @param beanType 对象中的object类型 |
||||
* @param <T> |
||||
* @return |
||||
*/ |
||||
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) { |
||||
try { |
||||
T t = MAPPER.readValue(jsonData, beanType); |
||||
return t; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 将json数据转换成pojo对象list |
||||
* |
||||
* @param jsonData |
||||
* @param beanType |
||||
* @param <T> |
||||
* @return |
||||
*/ |
||||
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) { |
||||
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType); |
||||
try { |
||||
List<T> list = MAPPER.readValue(jsonData, javaType); |
||||
return list; |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* set属性的值到Bean |
||||
* |
||||
* @param bean |
||||
* @param valMap |
||||
*/ |
||||
public synchronized static void setFieldValue(Object bean, Map<String, String> valMap) { |
||||
Class<?> cls = bean.getClass(); |
||||
// 取出bean里的所有方法
|
||||
Method[] methods = cls.getDeclaredMethods(); |
||||
Field[] fields = cls.getDeclaredFields(); |
||||
|
||||
for (Field field : fields) { |
||||
try { |
||||
String fieldSetName = parSetName(field.getName(), false); |
||||
if (!checkSetMet(methods, fieldSetName)) { |
||||
fieldSetName = parSetName(field.getName(), true); |
||||
if (!checkSetMet(methods, fieldSetName)) { |
||||
continue; |
||||
} |
||||
} |
||||
Method fieldSetMet = cls.getMethod(fieldSetName, field.getType()); |
||||
String value = valMap.get(field.getName()); |
||||
if (null != value && !"".equals(value)) { |
||||
String fieldType = field.getType().getSimpleName(); |
||||
if ("String".equals(fieldType)) { |
||||
fieldSetMet.invoke(bean, value); |
||||
} else if ("Date".equals(fieldType)) { |
||||
Date temp = parseDate(value); |
||||
fieldSetMet.invoke(bean, temp); |
||||
} else if ("Integer".equals(fieldType) || "int".equals(fieldType)) { |
||||
Integer intval = Integer.parseInt(value); |
||||
fieldSetMet.invoke(bean, intval); |
||||
} else if ("Long".equalsIgnoreCase(fieldType)) { |
||||
Long temp = Long.parseLong(value); |
||||
fieldSetMet.invoke(bean, temp); |
||||
} else if ("Double".equalsIgnoreCase(fieldType)) { |
||||
Double temp = Double.parseDouble(value); |
||||
fieldSetMet.invoke(bean, temp); |
||||
} else if ("Boolean".equalsIgnoreCase(fieldType)) { |
||||
Boolean temp = Boolean.parseBoolean(value); |
||||
fieldSetMet.invoke(bean, temp); |
||||
} else if ("Date".equalsIgnoreCase(fieldType)) { |
||||
Date temp = parseDate(value); |
||||
fieldSetMet.invoke(bean, temp); |
||||
} else if ("BigDecimal".equals(fieldType)) { |
||||
BigDecimal temp = new BigDecimal(value); |
||||
fieldSetMet.invoke(bean, temp); |
||||
} else { |
||||
// throw new Jc("500","not supper type" + fieldType);
|
||||
} |
||||
} |
||||
} catch (Exception e) { |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
/** |
||||
* 拼接某属性的 get方法 |
||||
* |
||||
* @param fieldName |
||||
* @return String |
||||
*/ |
||||
private static String parGetName(String fieldName, boolean firstLow) { |
||||
if (null == fieldName || "".equals(fieldName)) { |
||||
return null; |
||||
} |
||||
if (firstLow && fieldName.length() > 1) { //判断是否为 第一个字母小写,第二个字母大写
|
||||
if (Character.isLowerCase(fieldName.charAt(0)) && Character.isUpperCase(fieldName.charAt(1))) { |
||||
return "get" + fieldName; |
||||
} |
||||
} |
||||
return "get" + fieldName.substring(0, 1).toUpperCase() |
||||
+ fieldName.substring(1); |
||||
} |
||||
|
||||
/** |
||||
* 拼接在某属性的 set方法 |
||||
* |
||||
* @param fieldName |
||||
* @return String |
||||
*/ |
||||
private static String parSetName(String fieldName, boolean firstLow) { |
||||
if (null == fieldName || "".equals(fieldName)) { |
||||
return null; |
||||
} |
||||
if (firstLow && fieldName.length() > 1) { //判断是否为 第一个字母小写,第二个字母大写
|
||||
if (Character.isLowerCase(fieldName.charAt(0)) && Character.isUpperCase(fieldName.charAt(1))) { |
||||
return "set" + fieldName; |
||||
} |
||||
} |
||||
return "set" + fieldName.substring(0, 1).toUpperCase() |
||||
+ fieldName.substring(1); |
||||
} |
||||
|
||||
/** |
||||
* 格式化string为Date |
||||
* |
||||
* @param datestr |
||||
* @return date |
||||
*/ |
||||
private static Date parseDate(String datestr) { |
||||
if (null == datestr || "".equals(datestr)) { |
||||
return null; |
||||
} |
||||
try { |
||||
String fmtstr = null; |
||||
if (datestr.indexOf(':') > 0) { |
||||
fmtstr = "yyyy-MM-dd HH:mm:ss"; |
||||
} else { |
||||
fmtstr = "yyyy-MM-dd"; |
||||
} |
||||
SimpleDateFormat sdf = new SimpleDateFormat(fmtstr, Locale.UK); |
||||
return sdf.parse(datestr); |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 日期转化为String |
||||
* |
||||
* @param date |
||||
* @return date string |
||||
*/ |
||||
private static String fmtDate(Date date) { |
||||
if (null == date) { |
||||
return null; |
||||
} |
||||
try { |
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); |
||||
return sdf.format(date); |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 判断是否存在某属性的 set方法 |
||||
* |
||||
* @param methods |
||||
* @param fieldSetMet |
||||
* @return boolean |
||||
*/ |
||||
private static boolean checkSetMet(Method[] methods, String fieldSetMet) { |
||||
for (Method met : methods) { |
||||
if (fieldSetMet.equals(met.getName())) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* 判断是否存在某属性的 get方法 |
||||
* |
||||
* @param methods |
||||
* @param fieldGetMet |
||||
* @return boolean |
||||
*/ |
||||
private static boolean checkGetMet(Method[] methods, String fieldGetMet) { |
||||
for (Method met : methods) { |
||||
if (fieldGetMet.equals(met.getName())) { |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* 使用json的方式转换两个pojo类(源是包含下划线属性的) |
||||
* |
||||
* @param source 源对象 |
||||
* @param destCls 目标类 |
||||
* @param <D> |
||||
* @return 目标对象 |
||||
*/ |
||||
public static <D> D mapLowerCaseWithUnderscoresSource(Object source, Class<D> destCls) { |
||||
String sourceJson = objectToJson(source); |
||||
ObjectMapper objectMapper = new ObjectMapper(); |
||||
/** 设置映射下划线 */ |
||||
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); |
||||
try { |
||||
return objectMapper.readValue(sourceJson, destCls); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
public static <S, D> Map<S, D> jsonToHashMap(String sourceJson, Class<S> sourceClazz, Class<D> destClazz) { |
||||
try { |
||||
return MAPPER.readValue(sourceJson, MAPPER.getTypeFactory().constructMapType(HashMap.class, sourceClazz, destClazz)); |
||||
} catch (IOException e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,38 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import java.security.MessageDigest; |
||||
|
||||
/** |
||||
* \* <p>Desciption:MD5加密工具类</p> |
||||
* \* CreateTime: 2018/3/12 12:29 |
||||
* \* User: XianChaoWei |
||||
* \* Version: V1.0 |
||||
* \ |
||||
*/ |
||||
public class MD5Utils { |
||||
public final static String MD5(String s) { |
||||
char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; |
||||
try { |
||||
byte[] btInput = s.getBytes(); |
||||
// 获得MD5摘要算法的 MessageDigest 对象
|
||||
MessageDigest mdInst = MessageDigest.getInstance("MD5"); |
||||
// 使用指定的字节更新摘要
|
||||
mdInst.update(btInput); |
||||
// 获得密文
|
||||
byte[] md = mdInst.digest(); |
||||
// 把密文转换成十六进制的字符串形式
|
||||
int j = md.length; |
||||
char str[] = new char[j * 2]; |
||||
int k = 0; |
||||
for (int i = 0; i < j; i++) { |
||||
byte byte0 = md[i]; |
||||
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; |
||||
str[k++] = hexDigits[byte0 & 0xf]; |
||||
} |
||||
return new String(str); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
return null; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,265 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import com.blockchain.common.base.dto.TokenDTO; |
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import org.apache.commons.codec.binary.Base64; |
||||
import org.apache.commons.codec.binary.StringUtils; |
||||
|
||||
import javax.crypto.Cipher; |
||||
import java.security.*; |
||||
import java.security.spec.PKCS8EncodedKeySpec; |
||||
import java.security.spec.X509EncodedKeySpec; |
||||
|
||||
/** |
||||
* \* <p>Desciption:</p> |
||||
* \* CreateTime: 2018/12/1 11:18 |
||||
* \* User: XianChaoWei |
||||
* \* Version: V1.0 |
||||
* \ |
||||
*/ |
||||
public class RSACoderUtils { |
||||
//非对称密钥算法
|
||||
private static final String KEY_ALGORITHM = "RSA"; |
||||
|
||||
/** |
||||
* 密钥长度,DH算法的默认密钥长度是1024 |
||||
* 密钥长度必须是64的倍数,在512到65536位之间 |
||||
*/ |
||||
private static final int KEY_SIZE = 1024; |
||||
|
||||
//公钥
|
||||
public static final byte[] publicKey = {48, -127, -97, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, |
||||
3, -127, -115, 0, 48, -127, -119, 2, -127, -127, 0, -128, 48, -25, 69, -64, -57, -59, -64, -116, -5, -4, |
||||
-26, -5, 109, 17, 59, 68, -69, -16, -110, 19, -21, -78, 25, 77, -40, 18, 77, 2, 70, -45, 15, 112, 57, 111 |
||||
, 14, 78, -69, 18, -115, 21, 9, -38, 126, -107, -116, -124, -95, -116, 6, 18, 57, -73, -25, -9, 46, 69, 1 |
||||
, 127, -27, -92, 2, -119, 106, -33, -78, -35, -26, 72, -65, 116, 61, -53, 85, 94, 68, -84, -121, 55, -68, |
||||
77, -128, 6, -99, 81, -5, 80, 52, 68, 53, -27, 79, -14, 37, 41, -18, 70, 96, -65, -32, -82, 75, -23, -77, |
||||
-39, -36, -46, 120, 7, 67, 101, 107, 58, 97, 66, 72, -52, -128, -62, 39, -121, -47, -73, 73, -100, 49, 9, |
||||
113, 2, 3, 1, 0, 1}; |
||||
//私钥
|
||||
public static final byte[] privateKey = {48, -126, 2, 118, 2, 1, 0, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, |
||||
1, 1, 5, 0, 4, -126, 2, 96, 48, -126, 2, 92, 2, 1, 0, 2, -127, -127, 0, -128, 48, -25, 69, -64, -57, -59, |
||||
-64, -116, -5, -4, -26, -5, 109, 17, 59, 68, -69, -16, -110, 19, -21, -78, 25, 77, -40, 18, 77, 2, 70, |
||||
-45, 15, 112, 57, 111, 14, 78, -69, 18, -115, 21, 9, -38, 126, -107, -116, -124, -95, -116, 6, 18, 57, |
||||
-73, -25, -9, 46, 69, 1, 127, -27, -92, 2, -119, 106, -33, -78, -35, -26, 72, -65, 116, 61, -53, 85, 94, |
||||
68, -84, -121, 55, -68, 77, -128, 6, -99, 81, -5, 80, 52, 68, 53, -27, 79, -14, 37, 41, -18, 70, 96, -65, |
||||
-32, -82, 75, -23, -77, -39, -36, -46, 120, 7, 67, 101, 107, 58, 97, 66, 72, -52, -128, -62, 39, -121, |
||||
-47, -73, 73, -100, 49, 9, 113, 2, 3, 1, 0, 1, 2, -127, -128, 103, -35, 55, -59, -64, -119, 28, -91, 2, |
||||
-106, 57, 55, 61, -120, 5, 106, 44, 42, -54, -92, -47, 23, 43, 90, 109, 68, 32, -81, -36, -92, 93, -26, |
||||
40, 91, -96, -85, -53, 6, -81, -27, 55, -94, -96, 49, -24, 33, -50, 100, -59, -5, 53, 81, 38, -68, -1, -3 |
||||
, -79, 83, -95, -71, 2, -58, 59, 103, -13, -78, -15, 56, 113, 53, -107, -98, 6, 54, -95, -110, -115, 88, |
||||
2, -122, -111, 9, 29, 22, -78, -21, 105, -95, -74, -62, 109, -31, -48, -75, 101, 112, 103, 26, 11, -126, |
||||
97, 48, 115, -74, 47, 122, -14, 97, -55, 77, 49, 7, -105, -87, 58, 21, -117, 98, -28, 27, -106, 113, -30, |
||||
-28, 45, -101, -109, 1, 2, 65, 0, -7, -37, 63, 25, -106, 28, 88, 14, -22, -47, -26, -117, 4, 55, -10, 37, |
||||
-73, 111, 75, 24, -123, 104, 42, -20, -46, -95, -119, -41, -82, -85, -11, -27, 41, -8, 38, 22, 112, -51, |
||||
35, 112, 23, -66, 4, -55, -6, 33, -121, -98, 35, 2, -64, -79, 118, -85, -83, -33, -103, -107, -33, 127, |
||||
-52, -115, 93, 25, 2, 65, 0, -125, 87, -47, -128, 76, -6, -66, 113, -107, 27, -58, -46, -15, -54, 59, -74 |
||||
, -98, -95, 16, -43, 109, 81, -79, 26, -57, 120, -82, 95, 66, 47, 105, 49, -92, -28, 61, 81, -60, 115, |
||||
-18, -84, 8, 99, 25, -123, -109, 46, -48, 115, -37, -13, 56, 6, -9, 36, -36, 112, -42, -8, 62, -87, 21, |
||||
70, -62, 25, 2, 65, 0, -16, -26, -89, 76, 48, 35, 91, -13, -26, 12, 67, 80, 61, -35, 7, 3, 14, 125, -53, |
||||
-43, -12, -86, -98, -40, 127, -83, 40, -114, 63, -25, -92, -54, 51, 81, 2, -56, 24, 50, 113, -68, -99, |
||||
-25, -92, 14, 105, -112, -14, -123, 82, 20, 81, 93, -55, -95, 117, -97, 101, 33, -49, -64, 20, -91, 39, |
||||
-31, 2, 64, 7, 23, 44, -106, 50, -111, -82, -54, 78, -12, 106, -19, 100, 100, 56, -119, 9, 83, 68, -89, |
||||
96, -7, 114, 8, 50, 16, -113, -55, 80, -73, 98, -124, 109, -108, 108, -61, 7, 74, 2, -18, -126, -99, 102, |
||||
-7, 81, 18, -53, -22, 21, 75, -78, 16, -98, 50, -3, 59, -110, 63, 96, -110, -100, 53, 111, -79, 2, 64, 80 |
||||
, -113, -19, 28, -46, -110, -75, 123, -29, -94, -19, -28, -64, -124, 87, 5, -4, 125, 35, -68, 68, -4, -60 |
||||
, -38, 123, -28, -34, -1, 1, 52, -11, 19, -32, -24, 83, 119, -4, 66, -93, -43, -3, 105, -106, 22, -39, |
||||
-55, 116, 91, -124, 39, -106, 37, -83, -39, 26, 118, 78, -87, 22, 76, 12, -110, 112, 77}; |
||||
|
||||
/** |
||||
* 初始化密钥对 |
||||
* |
||||
* @return |
||||
*/ |
||||
public static KeyPair initKey() throws Exception { |
||||
//实例化密钥生成器
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM); |
||||
//初始化密钥生成器
|
||||
keyPairGenerator.initialize(KEY_SIZE); |
||||
//生成密钥对
|
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair(); |
||||
return keyPair; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 私钥加密 |
||||
* |
||||
* @param data 待加密数据 |
||||
* @param key 密钥 |
||||
* @return byte[] 加密数据 |
||||
*/ |
||||
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception { |
||||
|
||||
//取得私钥
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); |
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); |
||||
//生成私钥
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); |
||||
//数据加密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
cipher.init(Cipher.ENCRYPT_MODE, privateKey); |
||||
return cipher.doFinal(data); |
||||
} |
||||
|
||||
/** |
||||
* 公钥加密 |
||||
* |
||||
* @param data 待加密数据 |
||||
* @param key 密钥 |
||||
* @return byte[] 加密数据 |
||||
*/ |
||||
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception { |
||||
|
||||
//实例化密钥工厂
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); |
||||
//初始化公钥
|
||||
//密钥材料转换
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); |
||||
//产生公钥
|
||||
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); |
||||
|
||||
//数据加密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
cipher.init(Cipher.ENCRYPT_MODE, pubKey); |
||||
return cipher.doFinal(data); |
||||
} |
||||
|
||||
/** |
||||
* 私钥解密 |
||||
* |
||||
* @param data 待解密数据 |
||||
* @param key 密钥 |
||||
* @return byte[] 解密数据 |
||||
*/ |
||||
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception { |
||||
//取得私钥
|
||||
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); |
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); |
||||
//生成私钥
|
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); |
||||
//数据解密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey); |
||||
return cipher.doFinal(data); |
||||
} |
||||
|
||||
/** |
||||
* 公钥解密 |
||||
* |
||||
* @param data 待解密数据 |
||||
* @param key 密钥 |
||||
* @return byte[] 解密数据 |
||||
*/ |
||||
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception { |
||||
|
||||
//实例化密钥工厂
|
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); |
||||
//初始化公钥
|
||||
//密钥材料转换
|
||||
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); |
||||
//产生公钥
|
||||
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); |
||||
//数据解密
|
||||
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); |
||||
cipher.init(Cipher.DECRYPT_MODE, pubKey); |
||||
return cipher.doFinal(data); |
||||
} |
||||
|
||||
/** |
||||
* 加密成token |
||||
* |
||||
* @param dto |
||||
* @return |
||||
*/ |
||||
public static String encryptToken(TokenDTO dto) { |
||||
try { |
||||
//转成json数据
|
||||
// String json = JsonUtils.objectToJson(dto);
|
||||
String json = dto.getTel() + "-" + dto.getTimestamp() + "-" + dto.getTokenType(); |
||||
//用私钥加密
|
||||
byte[] encrypt = RSACoderUtils.encryptByPrivateKey(json.getBytes(), privateKey); |
||||
//转成字符串
|
||||
return Base64.encodeBase64String(encrypt); |
||||
} catch (Exception e) { |
||||
throw new BaseException(BaseResultEnums.RSA_ERROR); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 解密获取用户数据 |
||||
* |
||||
* @param token |
||||
* @return |
||||
*/ |
||||
public static TokenDTO decryptToken(String token) { |
||||
try { |
||||
//转成数组
|
||||
byte[] decrypt = Base64.decodeBase64(StringUtils.getBytesUtf8(token)); |
||||
//解密
|
||||
byte[] bytes = RSACoderUtils.decryptByPublicKey(decrypt, publicKey); |
||||
//转成json数据
|
||||
String[] json = new String(bytes).split("-"); |
||||
TokenDTO tokenDTO = new TokenDTO(); |
||||
tokenDTO.setTel(json[0]); |
||||
tokenDTO.setTimestamp(new Long(json[1])); |
||||
tokenDTO.setTokenType(json[2]); |
||||
//返回token对象
|
||||
return tokenDTO; |
||||
} catch (Exception e) { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 加密私钥密码 |
||||
* |
||||
* @param data 私钥/密码 |
||||
* @return |
||||
*/ |
||||
public static String encryptPassword(String data) { |
||||
try { |
||||
//用私钥加密
|
||||
byte[] encrypt = RSACoderUtils.encryptByPrivateKey(data.getBytes(), privateKey); |
||||
//转成字符串
|
||||
return Base64.encodeBase64String(encrypt); |
||||
} catch (Exception e) { |
||||
throw new BaseException(BaseResultEnums.RSA_ERROR); |
||||
} |
||||
} |
||||
/** |
||||
* 解密获取密码 |
||||
* |
||||
* @param data 待解密数据 |
||||
* @return 密码 |
||||
*/ |
||||
public static String decryptPassword(String data) { |
||||
try { |
||||
byte[] dataByte = Base64.decodeBase64(data); |
||||
byte[] password = RSACoderUtils.decryptByPublicKey(dataByte, publicKey); |
||||
return new String(password); |
||||
} catch (Exception e) { |
||||
throw new BaseException(BaseResultEnums.PASSWORD_ERROR); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 根据私钥解密获取密码 |
||||
* |
||||
* @param data 待解密数据 |
||||
* @param key 私钥 |
||||
* @return 密码 |
||||
*/ |
||||
public static String decryptPassword(String data, String key) { |
||||
try { |
||||
byte[] dataByte = Base64.decodeBase64(data); |
||||
byte[] keyByte = Base64.decodeBase64(key); |
||||
byte[] password = RSACoderUtils.decryptByPrivateKey(dataByte, keyByte); |
||||
return new String(password); |
||||
} catch (Exception e) { |
||||
throw new BaseException(BaseResultEnums.PASSWORD_ERROR); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,162 @@ |
||||
package com.blockchain.common.base.util; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.constant.TokenTypeEnums; |
||||
import com.blockchain.common.base.dto.SessionUserDTO; |
||||
import com.blockchain.common.base.dto.TokenDTO; |
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.util.concurrent.TimeUnit; |
||||
|
||||
/** |
||||
* 单点登录工具类,使用token获取、设置用户信息 |
||||
*/ |
||||
public class SSOHelper { |
||||
private static final int TOKEN_INVALID_DAYS = 30;//token过期时间
|
||||
private static final int TOKEN_PC_INVALID_DAYS = 30;//token过期时间
|
||||
|
||||
/** |
||||
* 获取登录用户id |
||||
* |
||||
* @param redisTemplate redis |
||||
*/ |
||||
public static String getUserId(RedisTemplate redisTemplate, HttpServletRequest request) { |
||||
SessionUserDTO user = getUser(redisTemplate, request); |
||||
// resetTokenTTL(redisTemplate, user.getTel(), user);//重新设置过期时间
|
||||
return user.getId(); |
||||
} |
||||
|
||||
/*** |
||||
* 获取登录用户缓存信息 |
||||
* 已登录返回用户id |
||||
* 未登录返回null |
||||
* @param redisTemplate |
||||
* @param request |
||||
* @return |
||||
*/ |
||||
public static String getUserIdIsExits(RedisTemplate redisTemplate, HttpServletRequest request) { |
||||
SessionUserDTO effectiveUserIfExist = getEffectiveUserIfExist(redisTemplate, request); |
||||
if (effectiveUserIfExist == null) { |
||||
return null; |
||||
} |
||||
return effectiveUserIfExist.getId(); |
||||
} |
||||
|
||||
/** |
||||
* 检查用户登录状态 |
||||
*/ |
||||
public static void checkUser(RedisTemplate redisTemplate, HttpServletRequest request) { |
||||
getUser(redisTemplate, request); |
||||
} |
||||
|
||||
/** |
||||
* 获取登录用户缓存信息 |
||||
* |
||||
* @param redisTemplate redis |
||||
*/ |
||||
public static SessionUserDTO getUser(RedisTemplate redisTemplate, HttpServletRequest request) { |
||||
SessionUserDTO userDTO = getEffectiveUserIfExist(redisTemplate, request); |
||||
if (userDTO == null) { |
||||
throw new BaseException(BaseResultEnums.NO_LOGIN); |
||||
} |
||||
return userDTO; |
||||
} |
||||
|
||||
/** |
||||
* 设置用户 |
||||
* |
||||
* @param user 用户信息 |
||||
* @param redisTemplate redis |
||||
*/ |
||||
public static void setUser(SessionUserDTO user, RedisTemplate redisTemplate) { |
||||
setUser(user, redisTemplate, TokenTypeEnums.APP.getValue()); |
||||
} |
||||
|
||||
/** |
||||
* 设置用户 |
||||
* |
||||
* @param user 用户信息 |
||||
* @param redisTemplate redis |
||||
* @param tokenType tokenType |
||||
*/ |
||||
public static void setUser(SessionUserDTO user, RedisTemplate redisTemplate, String tokenType) { |
||||
if (StringUtils.isBlank(user.getTel())) { |
||||
throw new BaseException(BaseResultEnums.DEFAULT); |
||||
} |
||||
resetTokenTTL(redisTemplate, user.getTel(), user, tokenType); |
||||
} |
||||
|
||||
/** |
||||
* 移除用户token信息 |
||||
*/ |
||||
public static void removeUser(HttpServletRequest request, RedisTemplate redisTemplate) { |
||||
removeUser(request, redisTemplate, TokenTypeEnums.APP.getValue()); |
||||
} |
||||
|
||||
/** |
||||
* 移除用户token信息 |
||||
*/ |
||||
public static void removeUser(HttpServletRequest request, RedisTemplate redisTemplate, String tokenType) { |
||||
SessionUserDTO user = getEffectiveUserIfExist(redisTemplate, request); |
||||
if (user == null) { |
||||
return; |
||||
} |
||||
String tel = user.getTel(); |
||||
if (!StringUtils.isEmpty(tel)) { |
||||
String key = BaseConstant.REDIS_TOKEN_KEY + tel; |
||||
if (tokenType.equals(TokenTypeEnums.PC.getValue())) { |
||||
key = BaseConstant.REDIS_TOKEN_PC_KEY + tel; |
||||
} |
||||
if (redisTemplate.hasKey(key)) { |
||||
redisTemplate.delete(key); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 重置token过期时间 |
||||
* |
||||
* @param redisTemplate redis缓存 |
||||
* @param tel tel |
||||
* @param user 用户信息 |
||||
*/ |
||||
public static void resetTokenTTL(RedisTemplate redisTemplate, String tel, SessionUserDTO user, String tokenType) { |
||||
if (tokenType.equals(TokenTypeEnums.APP.getValue())) { |
||||
redisTemplate.opsForValue().set(BaseConstant.REDIS_TOKEN_KEY + tel, user, TOKEN_INVALID_DAYS, TimeUnit.DAYS); |
||||
} else { |
||||
redisTemplate.opsForValue().set(BaseConstant.REDIS_TOKEN_PC_KEY + tel, user, TOKEN_PC_INVALID_DAYS, TimeUnit.HOURS); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 获取登录用户缓存信息 |
||||
* |
||||
* @param redisTemplate redis |
||||
*/ |
||||
private static SessionUserDTO getEffectiveUserIfExist(RedisTemplate redisTemplate, HttpServletRequest request) { |
||||
String token = request.getHeader(BaseConstant.SSO_TOKEN_HEADER); |
||||
if (StringUtils.isEmpty(token)) { |
||||
return null; |
||||
} |
||||
TokenDTO tokenDTO = RSACoderUtils.decryptToken(token); |
||||
if (tokenDTO == null) { |
||||
return null; |
||||
} |
||||
String key = BaseConstant.REDIS_TOKEN_KEY + tokenDTO.getTel(); |
||||
if (tokenDTO.getTokenType().equals(TokenTypeEnums.PC.getValue())) { |
||||
key = BaseConstant.REDIS_TOKEN_PC_KEY + tokenDTO.getTel(); |
||||
} |
||||
if (redisTemplate.hasKey(key)) {//如果有token,拿到用户信息
|
||||
SessionUserDTO user = (SessionUserDTO) redisTemplate.opsForValue().get(key); |
||||
if (!user.getTimestamp().equals(tokenDTO.getTimestamp())) { |
||||
throw new BaseException(BaseResultEnums.LOGIN_REPLACED);//如果时间戳不对,则提示账号在别处登录
|
||||
} |
||||
return user; |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,230 @@ |
||||
<?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>blockchain-common</artifactId> |
||||
<groupId>com.blockchain</groupId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>blockchain-common-pom</artifactId> |
||||
|
||||
<properties> |
||||
<!-- mybatis --> |
||||
<mybatis-starter-version>1.3.2</mybatis-starter-version> |
||||
<mybatis-plugin-version>1.3.5</mybatis-plugin-version> |
||||
<tkmybatis.version>4.0.3</tkmybatis.version> |
||||
|
||||
<!-- 分页 --> |
||||
<PageHelper.version>5.1.1</PageHelper.version> |
||||
<springboot.pagehelper.version>1.2.3</springboot.pagehelper.version> |
||||
|
||||
<!-- 数据库驱动、连接池--> |
||||
<mysql-connector.version>5.1.39</mysql-connector.version> |
||||
<druid-starter-version>1.1.9</druid-starter-version> |
||||
|
||||
<!-- 当前微服务版本 --> |
||||
<last-blockchain-version>1.0-SNAPSHOT</last-blockchain-version> |
||||
<!-- swagger 文档--> |
||||
<swagger-ui.version>2.7.0</swagger-ui.version> |
||||
<swagger2.version>2.7.0</swagger2.version> |
||||
|
||||
<jsoup-version>1.11.3</jsoup-version> |
||||
<commons-lang3-version>3.7</commons-lang3-version> |
||||
<fastjson-version>1.2.47</fastjson-version> |
||||
<google-guava-version>23.0</google-guava-version> |
||||
<commons-codec-version>1.10</commons-codec-version> |
||||
|
||||
<!-- httpclient--> |
||||
<httpclient.version>4.3.5</httpclient.version> |
||||
</properties> |
||||
|
||||
|
||||
<dependencies> |
||||
<!-- ====spring boot start==== --> |
||||
<!-- web --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-web</artifactId> |
||||
</dependency> |
||||
<!-- aop --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-aop</artifactId> |
||||
</dependency> |
||||
<!--springboot 配置监控 用于重新获取与刷新1 --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-actuator</artifactId> |
||||
</dependency> |
||||
<!-- devtools --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-devtools</artifactId> |
||||
<optional>true</optional> |
||||
<scope>runtime</scope> |
||||
</dependency> |
||||
<!-- test --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-test</artifactId> |
||||
<scope>test</scope> |
||||
</dependency> |
||||
<!-- ====spring boot end==== --> |
||||
|
||||
<!-- ====redis缓存 start==== --> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-data-redis</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.session</groupId> |
||||
<artifactId>spring-session-data-redis</artifactId> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-cache</artifactId> |
||||
</dependency> |
||||
<!-- ====redis缓存 end==== --> |
||||
|
||||
<!-- ====spring cloud 微服务 start==== --> |
||||
<!-- 注册中心 --> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-config</artifactId> |
||||
</dependency> |
||||
<!-- 客户端 --> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> |
||||
</dependency> |
||||
<!-- 服务消费者 feign --> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-openfeign</artifactId> |
||||
</dependency> |
||||
<!-- 熔断器 --> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId> |
||||
</dependency> |
||||
<!-- commons --> |
||||
<dependency> |
||||
<groupId>org.springframework.cloud</groupId> |
||||
<artifactId>spring-cloud-commons</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- ====spring cloud 微服务 end==== --> |
||||
|
||||
<!-- ====Swagger start==== --> |
||||
<!--springfox的基本信息文档: http://springfox.github.io/springfox/docs/current/#architecture--> |
||||
<dependency> |
||||
<groupId>io.springfox</groupId> |
||||
<artifactId>springfox-swagger-ui</artifactId> |
||||
<version>${swagger-ui.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>io.springfox</groupId> |
||||
<artifactId>springfox-swagger2</artifactId> |
||||
<version>${swagger2.version}</version> |
||||
</dependency> |
||||
<!-- ====Swagger end==== --> |
||||
|
||||
<!-- ====持久层 start==== --> |
||||
<!-- 数据库 --> |
||||
<dependency> |
||||
<groupId>mysql</groupId> |
||||
<artifactId>mysql-connector-java</artifactId> |
||||
<version>${mysql-connector.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.mybatis.spring.boot</groupId> |
||||
<artifactId>mybatis-spring-boot-starter</artifactId> |
||||
<version>${mybatis-starter-version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.github.pagehelper</groupId> |
||||
<artifactId>pagehelper-spring-boot-starter</artifactId> |
||||
<version>${springboot.pagehelper.version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>tk.mybatis</groupId> |
||||
<artifactId>mapper</artifactId> |
||||
<version>${tkmybatis.version}</version> |
||||
</dependency> |
||||
<!-- druid starter --> |
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>druid-spring-boot-starter</artifactId> |
||||
<version>${druid-starter-version}</version> |
||||
</dependency> |
||||
<!-- ====持久层 end==== --> |
||||
|
||||
<!-- ====其他==== --> |
||||
<dependency> |
||||
<groupId>com.alibaba</groupId> |
||||
<artifactId>fastjson</artifactId> |
||||
<version>${fastjson-version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.apache.commons</groupId> |
||||
<artifactId>commons-lang3</artifactId> |
||||
<version>${commons-lang3-version}</version> |
||||
</dependency> |
||||
<!-- Java字符串、集合、并发、I/O和反射的协作工具类 --> |
||||
<dependency> |
||||
<groupId>com.google.guava</groupId> |
||||
<artifactId>guava</artifactId> |
||||
<version>${google-guava-version}</version> |
||||
</dependency> |
||||
<!-- HTML解析器 --> |
||||
<dependency> |
||||
<groupId>org.jsoup</groupId> |
||||
<artifactId>jsoup</artifactId> |
||||
<version>${jsoup-version}</version> |
||||
</dependency> |
||||
|
||||
<!-- httpclient --> |
||||
<dependency> |
||||
<groupId>org.apache.httpcomponents</groupId> |
||||
<artifactId>httpclient</artifactId> |
||||
<version>${httpclient.version}</version> |
||||
</dependency> |
||||
|
||||
<dependency> |
||||
<groupId>org.apache.commons</groupId> |
||||
<artifactId>commons-lang3</artifactId> |
||||
<version>${commons-lang3-version}</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>commons-codec</groupId> |
||||
<artifactId>commons-codec</artifactId> |
||||
<version>${commons-codec-version}</version> |
||||
</dependency> |
||||
|
||||
<!--websocket依赖包--> |
||||
<dependency> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-starter-websocket</artifactId> |
||||
</dependency> |
||||
|
||||
<!-- json-RPC --> |
||||
<dependency> |
||||
<groupId>com.github.briandilley.jsonrpc4j</groupId> |
||||
<artifactId>jsonrpc4j</artifactId> |
||||
<version>1.5.3</version> |
||||
</dependency> |
||||
|
||||
<!-- 阿里云依赖 --> |
||||
<dependency> |
||||
<groupId>com.aliyun</groupId> |
||||
<artifactId>aliyun-java-sdk-core</artifactId> |
||||
<version>4.0.3</version> |
||||
</dependency> |
||||
|
||||
</dependencies> |
||||
|
||||
</project> |
@ -0,0 +1,45 @@ |
||||
<?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>blockchain-common</artifactId> |
||||
<groupId>com.blockchain</groupId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>blockchain-common-tx</artifactId> |
||||
|
||||
<properties> |
||||
<!-- 分布式事务 --> |
||||
<lcn.last.version>4.2.0-SNAPSHOT</lcn.last.version> |
||||
<io-netty-version>4.1.12.Final</io-netty-version> |
||||
</properties> |
||||
<dependencies> |
||||
<!-- 分布式事务 --> |
||||
<dependency> |
||||
<groupId>com.codingapi</groupId> |
||||
<artifactId>transaction-springcloud</artifactId> |
||||
<version>${lcn.last.version}</version> |
||||
<exclusions> |
||||
<exclusion> |
||||
<groupId>org.slf4j</groupId> |
||||
<artifactId>*</artifactId> |
||||
</exclusion> |
||||
</exclusions> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.codingapi</groupId> |
||||
<artifactId>tx-plugins-db</artifactId> |
||||
<version>${lcn.last.version}</version> |
||||
<exclusions> |
||||
<exclusion> |
||||
<groupId>org.slf4j</groupId> |
||||
<artifactId>*</artifactId> |
||||
</exclusion> |
||||
</exclusions> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
</project> |
@ -0,0 +1,8 @@ |
||||
##分布式事务配置: |
||||
如果模块需要分布式事务 |
||||
1. 引入pom依赖 |
||||
<dependency> |
||||
<groupId>com.blockchain</groupId> |
||||
<artifactId>blockchain-common-tx</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</dependency> |
@ -0,0 +1,22 @@ |
||||
<?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>blockchain</artifactId> |
||||
<groupId>com.blockchain</groupId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>blockchain-common</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
<packaging>pom</packaging> |
||||
<modules> |
||||
<module>blockchain-common-base</module> |
||||
<module>blockchain-common-pom</module> |
||||
<module>blockchain-common-tx</module> |
||||
</modules> |
||||
|
||||
|
||||
</project> |
@ -0,0 +1,15 @@ |
||||
<?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>blockchain-server</artifactId> |
||||
<groupId>com.blockchain</groupId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>blockchain-server-base</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
|
||||
</project> |
@ -0,0 +1,8 @@ |
||||
package com.blockchain.server.base; |
||||
|
||||
/** |
||||
* @author huangxl |
||||
* @create 2018-11-12 13:53 |
||||
*/ |
||||
public class BaseConf { |
||||
} |
@ -0,0 +1,13 @@ |
||||
package com.blockchain.server.base.annotation; |
||||
|
||||
import java.lang.annotation.*; |
||||
|
||||
/*** |
||||
* 用于注解不需要处理feign返回值的类或方法 |
||||
*/ |
||||
@Target({ElementType.TYPE, ElementType.METHOD}) |
||||
@Retention(RetentionPolicy.RUNTIME) |
||||
@Documented |
||||
public @interface BypassedFeign { |
||||
String value() default ""; |
||||
} |
@ -0,0 +1,68 @@ |
||||
package com.blockchain.server.base.aop; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import com.blockchain.common.base.exception.RPCException; |
||||
import com.blockchain.server.base.annotation.BypassedFeign; |
||||
import org.aspectj.lang.JoinPoint; |
||||
import org.aspectj.lang.annotation.AfterReturning; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.annotation.Pointcut; |
||||
import org.aspectj.lang.reflect.MethodSignature; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
@Aspect |
||||
@Component |
||||
public class FeignAop { |
||||
private Logger LOG = LoggerFactory.getLogger(getClass()); |
||||
|
||||
//Feign调用成功返回码
|
||||
private static final int REQUEST_SUCCESS = BaseConstant.REQUEST_SUCCESS; |
||||
|
||||
/*** |
||||
* 设置切入点 |
||||
* 切所有模块的Feign包的所有方法 |
||||
*/ |
||||
@Pointcut("execution(* com.blockchain.server.*.feign..*.*(..))") |
||||
public void handleResultDTO() { |
||||
} |
||||
|
||||
/*** |
||||
* 请求结束返回时处理 |
||||
* @param resultDTO |
||||
*/ |
||||
@AfterReturning(returning = "resultDTO", pointcut = "handleResultDTO()") |
||||
public void doAfterReturning(JoinPoint joinPoint, ResultDTO resultDTO) { |
||||
//调用的方法名
|
||||
String methodName = joinPoint.getSignature().getName(); |
||||
//调用的类名
|
||||
String simpleName = joinPoint.getTarget().getClass().getSimpleName(); |
||||
//获取方法对象
|
||||
Method method = ((MethodSignature) joinPoint.getSignature()).getMethod(); |
||||
//判断该方法上注解是否存在
|
||||
boolean isAnno = method.isAnnotationPresent(BypassedFeign.class); |
||||
LOG.info(method.getName() + resultDTO.toString()); |
||||
//如果存在注解,则不处理
|
||||
if (isAnno) { |
||||
LOG.error("BypassedFeign不处理的内部接口:返回信息{},类名{},方法名{}", resultDTO.toString(), simpleName, methodName); |
||||
return; |
||||
} |
||||
//返回值为空
|
||||
if (resultDTO == null) { |
||||
LOG.error("feign返回为空:类名{},方法名{}", simpleName, methodName); |
||||
throw new BaseException(BaseResultEnums.BUSY); |
||||
} |
||||
//RPC调用返回码不等于200,抛出异常
|
||||
if (resultDTO.getCode() != REQUEST_SUCCESS) { |
||||
LOG.error("返回信息{},类名{},方法名{}", resultDTO.toString(), simpleName, methodName); |
||||
throw new RPCException(resultDTO); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,66 @@ |
||||
package com.blockchain.server.base.aop; |
||||
|
||||
import com.blockchain.common.base.util.JsonUtils; |
||||
import org.aspectj.lang.JoinPoint; |
||||
import org.aspectj.lang.ProceedingJoinPoint; |
||||
import org.aspectj.lang.annotation.AfterThrowing; |
||||
import org.aspectj.lang.annotation.Around; |
||||
import org.aspectj.lang.annotation.Aspect; |
||||
import org.aspectj.lang.annotation.Pointcut; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.Arrays; |
||||
|
||||
@Aspect |
||||
@Component |
||||
public class MethodAop { |
||||
private Logger logger = LoggerFactory.getLogger(getClass()); |
||||
|
||||
@Pointcut("execution(* com.blockchain.server.*.service.*.update*(..))," + |
||||
"execution(* com.blockchain.server.*.service.*.delete*(..))") |
||||
public void aopPoint() { |
||||
} |
||||
|
||||
@Around("aopPoint()") |
||||
public Object around(ProceedingJoinPoint joinPoint) throws Throwable { |
||||
/** 获取方法名 */ |
||||
String methodName = joinPoint.getSignature().getName(); |
||||
logger.info("=================== {}方法开始执行 ===================", methodName); |
||||
logger.info("=================== 执行的参数有:{} ===================", Arrays.toString(joinPoint.getArgs())); |
||||
long start = System.currentTimeMillis(); |
||||
Object proceed = joinPoint.proceed(); |
||||
long end = System.currentTimeMillis(); |
||||
logger.info("=================== {}方法执行时使用了{}毫秒 ===================", methodName, (end - start)); |
||||
|
||||
logger.info("=================== {}方法执行后返回的数据是{} ===================", JsonUtils.objectToJson(proceed)); |
||||
|
||||
logger.info("=================== {}方法结束执行 ===================", methodName); |
||||
|
||||
return proceed; |
||||
} |
||||
|
||||
@Pointcut("execution(* com.blockchain.server.*.service.*.*.*(..))") |
||||
public void aopPoint2() { |
||||
} |
||||
|
||||
@AfterThrowing(throwing = "ex", value = "aopPoint2()") |
||||
public void errorAop(JoinPoint joinPoint, Throwable ex) { |
||||
/* 出现异常的类名 */ |
||||
String className = joinPoint.getTarget().getClass().getSimpleName(); |
||||
/*出现异常的方法名*/ |
||||
String methodName = joinPoint.getSignature().getName(); |
||||
/*传递的参数*/ |
||||
Object[] args = joinPoint.getArgs(); |
||||
/*异常类*/ |
||||
String exName = ex.getClass().getName(); |
||||
/*异常信息*/ |
||||
String exMsg = ex.getMessage(); |
||||
|
||||
Object[] params = {className, methodName, exName, args, exMsg}; |
||||
|
||||
logger.error("{}类的{}出现了{}异常,参数是:{},异常信息是:{}", params); |
||||
// logger.error(exMsg, ex);
|
||||
} |
||||
} |
@ -0,0 +1,26 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import com.blockchain.server.base.interceptor.StringToDateConverter; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.core.convert.support.GenericConversionService; |
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; |
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; |
||||
|
||||
import javax.annotation.PostConstruct; |
||||
|
||||
@Configuration |
||||
public class DateConvertConfig { |
||||
@Autowired |
||||
private RequestMappingHandlerAdapter handlerAdapter; |
||||
|
||||
@PostConstruct |
||||
public void addDateConvert() { |
||||
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) handlerAdapter.getWebBindingInitializer(); |
||||
if (initializer != null) { |
||||
System.out.println("===============DateConvertConfig==================="); |
||||
GenericConversionService conversionService = (GenericConversionService) initializer.getConversionService(); |
||||
conversionService.addConverter(new StringToDateConverter()); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,32 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import feign.RequestInterceptor; |
||||
import feign.RequestTemplate; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.util.Enumeration; |
||||
|
||||
@Configuration |
||||
public class FeginConf implements RequestInterceptor { |
||||
|
||||
@Override |
||||
public void apply(RequestTemplate requestTemplate) { |
||||
requestTemplate.header("X-Real-IP", "127.0.0.1"); |
||||
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
||||
if (attributes == null) { |
||||
return; |
||||
} |
||||
HttpServletRequest request = attributes.getRequest(); |
||||
Enumeration<String> headerNames = request.getHeaderNames(); |
||||
if (headerNames != null) { |
||||
while (headerNames.hasMoreElements()) { |
||||
String name = headerNames.nextElement(); |
||||
String values = request.getHeader(name); |
||||
requestTemplate.header(name, values); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,73 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import com.blockchain.common.base.exception.RPCException; |
||||
import com.blockchain.common.base.util.HttpRequestUtil; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.web.bind.annotation.ControllerAdvice; |
||||
import org.springframework.web.bind.annotation.ExceptionHandler; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.util.Date; |
||||
|
||||
/** |
||||
* @author huangxl |
||||
* 全局拦截器 |
||||
*/ |
||||
@RestController |
||||
@ControllerAdvice |
||||
public class GlobalExceptionHandle { |
||||
private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandle.class); |
||||
|
||||
/** |
||||
* 处理参数异常 |
||||
* |
||||
* @param e 异常信息 |
||||
* @return 返回内容 |
||||
*/ |
||||
@ExceptionHandler(BaseException.class) |
||||
public ResultDTO handleInvalidArgumentException(BaseException e) { |
||||
e.printStackTrace(); |
||||
return new ResultDTO(e.getCode(), e.getMsg(), null); |
||||
} |
||||
|
||||
/** |
||||
* 处理rpc调用异常 |
||||
* |
||||
* @param e 异常信息 |
||||
* @return 返回内容 |
||||
*/ |
||||
@ExceptionHandler(RPCException.class) |
||||
public ResultDTO handleRPCException(RPCException e) { |
||||
e.printStackTrace(); |
||||
return new ResultDTO(e.getCode(), e.getMsg(), null); |
||||
} |
||||
|
||||
/** |
||||
* 处理未知异常 |
||||
* |
||||
* @param e 异常信息 |
||||
* @return 返回内容 |
||||
*/ |
||||
@ExceptionHandler(Exception.class) |
||||
public ResultDTO handleUnknownException(Exception e) { |
||||
LOG.error("{}系统抛出异常,异常是:{},异常信息是:{}", new Date(), e.getClass().getName(), e.getMessage()); |
||||
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); |
||||
HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); |
||||
if (request != null) { |
||||
LOG.error("请求路径:{}", request.getRequestURL().toString()); |
||||
} |
||||
if (response != null) { |
||||
LOG.error("响应头:{}", response.getHeader("Content-Type")); |
||||
} |
||||
e.printStackTrace(); |
||||
BaseException base = new BaseException(); |
||||
return new ResultDTO(base.getCode(), base.getMsg(), null); |
||||
} |
||||
} |
@ -0,0 +1,27 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import com.blockchain.server.base.interceptor.InnerInterceptor; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry; |
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||
|
||||
//@Configuration
|
||||
public class InnerInterceptorConf implements WebMvcConfigurer { |
||||
@Bean |
||||
public InnerInterceptor innerInterceptor() { |
||||
return new InnerInterceptor(); |
||||
} |
||||
|
||||
@Override |
||||
public void addInterceptors(InterceptorRegistry registry) { |
||||
registry.addInterceptor(innerInterceptor()) |
||||
.addPathPatterns("/inner/**"); |
||||
} |
||||
|
||||
@Override |
||||
public void addCorsMappings(CorsRegistry registry) { |
||||
registry.addMapping("/**").allowedOrigins("*"); |
||||
} |
||||
} |
@ -0,0 +1,91 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect; |
||||
import com.fasterxml.jackson.annotation.PropertyAccessor; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.cache.CacheManager; |
||||
import org.springframework.cache.annotation.CachingConfigurerSupport; |
||||
import org.springframework.cache.annotation.EnableCaching; |
||||
import org.springframework.cache.interceptor.KeyGenerator; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration; |
||||
import org.springframework.data.redis.cache.RedisCacheManager; |
||||
import org.springframework.data.redis.cache.RedisCacheWriter; |
||||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; |
||||
import org.springframework.data.redis.serializer.StringRedisSerializer; |
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.time.Duration; |
||||
|
||||
/** |
||||
* @author huangxl |
||||
* Created on 2018/8/26 |
||||
*/ |
||||
@Configuration |
||||
@EnableCaching |
||||
@EnableRedisHttpSession |
||||
public class RedisConf extends CachingConfigurerSupport { |
||||
@Value("${spring.redis.cache.timeout-seconds}") |
||||
private long redisDefaultTtl; |
||||
|
||||
@Bean |
||||
public KeyGenerator keyGenerator() { |
||||
return new KeyGenerator() { |
||||
@Override |
||||
public Object generate(Object target, Method method, Object... params) { |
||||
StringBuilder sb = new StringBuilder(); |
||||
sb.append(target.getClass().getName()); |
||||
sb.append(method.getName()); |
||||
for (Object obj : params) { |
||||
sb.append(obj.toString()); |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Bean |
||||
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { |
||||
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig() |
||||
.entryTtl(Duration.ofMillis(redisDefaultTtl)); // 设置缓存有效期一小时
|
||||
return RedisCacheManager |
||||
.builder(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory)) |
||||
.cacheDefaults(redisCacheConfiguration).build(); |
||||
} |
||||
|
||||
/** |
||||
* 设置redis 键、值的序列化,防止乱码 |
||||
*/ |
||||
@Bean |
||||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) { |
||||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); |
||||
redisTemplate.setConnectionFactory(redisConnectionFactory); |
||||
|
||||
// 使用Jackson2JsonRedisSerialize 替换默认序列化
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); |
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper(); |
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); |
||||
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); |
||||
|
||||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper); |
||||
|
||||
// 设置value的序列化规则和 key的序列化规则
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); |
||||
redisTemplate.setKeySerializer(new StringRedisSerializer()); |
||||
|
||||
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer); |
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); |
||||
|
||||
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer); |
||||
redisTemplate.setEnableDefaultSerializer(true); |
||||
redisTemplate.afterPropertiesSet(); |
||||
return redisTemplate; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,24 @@ |
||||
package com.blockchain.server.base.conf; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.http.client.ClientHttpRequestFactory; |
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory; |
||||
import org.springframework.web.client.RestTemplate; |
||||
|
||||
/** |
||||
* RestTemplate配置类 |
||||
*/ |
||||
@Configuration |
||||
public class RestTemplateConf { |
||||
@Bean |
||||
public RestTemplate restTemplate(ClientHttpRequestFactory factory){ |
||||
return new RestTemplate(factory); |
||||
} |
||||
@Bean |
||||
public ClientHttpRequestFactory simpleClientHttpRequestFactory(){ |
||||
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); |
||||
factory.setReadTimeout(5000);//单位为ms
|
||||
factory.setConnectTimeout(5000);//单位为ms
|
||||
return factory; |
||||
} |
||||
} |
@ -0,0 +1,19 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker; |
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; |
||||
import org.springframework.cloud.netflix.eureka.EnableEurekaClient; |
||||
import org.springframework.cloud.openfeign.EnableFeignClients; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
/** |
||||
* @author huangxl |
||||
* @create 2018-11-13 13:48 |
||||
*/ |
||||
@Configuration |
||||
@EnableEurekaClient //注册客户端
|
||||
@EnableFeignClients(basePackages = "com.blockchain.server.*.feign") |
||||
@EnableCircuitBreaker //熔断器
|
||||
@EnableDiscoveryClient //服务发现
|
||||
public class SpringCloudConf { |
||||
} |
@ -0,0 +1,40 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import springfox.documentation.builders.ApiInfoBuilder; |
||||
import springfox.documentation.builders.PathSelectors; |
||||
import springfox.documentation.builders.RequestHandlerSelectors; |
||||
import springfox.documentation.service.ApiInfo; |
||||
import springfox.documentation.spi.DocumentationType; |
||||
import springfox.documentation.spring.web.plugins.Docket; |
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2; |
||||
|
||||
/** |
||||
* <p>Desciption:</p> |
||||
* CreateTime: 2018/3/19 11:26 |
||||
* User: XianChaoWei |
||||
* Version: V1.0 |
||||
*/ |
||||
@Configuration |
||||
@EnableSwagger2 |
||||
public class SwaggerConf { |
||||
|
||||
@Bean |
||||
public Docket createRestApi() { |
||||
return new Docket(DocumentationType.SWAGGER_2) |
||||
.apiInfo(apiInfo()) |
||||
.select() |
||||
.apis(RequestHandlerSelectors.basePackage("com.blockchain.server")) |
||||
.paths(PathSelectors.any()) |
||||
.build(); |
||||
} |
||||
|
||||
private ApiInfo apiInfo() { |
||||
return new ApiInfoBuilder() |
||||
.title("接口文档API") |
||||
.description("接口文档") |
||||
.version("1.0") |
||||
.build(); |
||||
} |
||||
} |
@ -0,0 +1,17 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import tk.mybatis.spring.mapper.MapperScannerConfigurer; |
||||
|
||||
@Configuration |
||||
public class TkMybatisConf { |
||||
private static final String MAPPER_PACKAGE = "com.blockchain.server.*.mapper"; |
||||
|
||||
@Bean |
||||
public MapperScannerConfigurer mapperScannerConfigurer(){ |
||||
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); |
||||
mapperScannerConfigurer.setBasePackage(MAPPER_PACKAGE); |
||||
return mapperScannerConfigurer; |
||||
} |
||||
} |
@ -0,0 +1,45 @@ |
||||
package com.blockchain.server.base.conf; |
||||
|
||||
import com.blockchain.server.base.filter.XssFilter; |
||||
import com.google.common.collect.Maps; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
|
||||
import javax.servlet.DispatcherType; |
||||
import java.util.Map; |
||||
|
||||
/** |
||||
* XssFilter配置 |
||||
*/ |
||||
@Configuration |
||||
public class XssFilterConfig |
||||
{ |
||||
@Value("${xss.enabled}") |
||||
private String enabled; |
||||
|
||||
@Value("${xss.excludes}") |
||||
private String excludes; |
||||
|
||||
@Value("${xss.urlPatterns}") |
||||
private String urlPatterns; |
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" }) |
||||
@Bean |
||||
public FilterRegistrationBean xssFilterRegistration() |
||||
{ |
||||
FilterRegistrationBean registration = new FilterRegistrationBean(); |
||||
registration.setDispatcherTypes(DispatcherType.REQUEST); |
||||
registration.setFilter(new XssFilter()); |
||||
registration.addUrlPatterns(StringUtils.split(urlPatterns, ",")); |
||||
registration.setName("xssFilter"); |
||||
registration.setOrder(Integer.MAX_VALUE); |
||||
Map<String, String> initParameters = Maps.newHashMap(); |
||||
initParameters.put("excludes", excludes); |
||||
initParameters.put("enabled", enabled); |
||||
registration.setInitParameters(initParameters); |
||||
return registration; |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
package com.blockchain.server.base.controller; |
||||
|
||||
import com.blockchain.common.base.dto.PageDTO; |
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.github.pagehelper.PageInfo; |
||||
|
||||
import java.util.List; |
||||
|
||||
public class BaseController { |
||||
|
||||
/** |
||||
* 构造分页对象 |
||||
* <p> |
||||
* 构造控制层返回分页对象 |
||||
* <p> |
||||
* 后台控制层统一返回该方法 |
||||
* |
||||
* @param list |
||||
* @return |
||||
*/ |
||||
protected <T> ResultDTO<PageDTO> generatePage(List<T> list) { |
||||
//通过构造器生成一个分页信息对象
|
||||
PageInfo pageInfo = new PageInfo(list); |
||||
//构造返回前端分页信息DTO
|
||||
PageDTO pageDTO = new PageDTO(pageInfo.getTotal(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getList()); |
||||
return ResultDTO.requstSuccess(pageDTO); |
||||
} |
||||
} |
@ -0,0 +1,92 @@ |
||||
package com.blockchain.server.base.filter; |
||||
|
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import javax.servlet.*; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
import java.io.IOException; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
import java.util.regex.Matcher; |
||||
import java.util.regex.Pattern; |
||||
|
||||
/** |
||||
* 防止XSS攻击的过滤器 |
||||
*/ |
||||
public class XssFilter implements Filter |
||||
{ |
||||
/** |
||||
* 排除链接 |
||||
*/ |
||||
public List<String> excludes = new ArrayList<>(); |
||||
|
||||
/** |
||||
* xss过滤开关 |
||||
*/ |
||||
public boolean enabled = false; |
||||
|
||||
@Override |
||||
public void init(FilterConfig filterConfig) throws ServletException |
||||
{ |
||||
String tempExcludes = filterConfig.getInitParameter("excludes"); |
||||
String tempEnabled = filterConfig.getInitParameter("enabled"); |
||||
if (StringUtils.isNotEmpty(tempExcludes)) |
||||
{ |
||||
String[] url = tempExcludes.split(","); |
||||
for (int i = 0; url != null && i < url.length; i++) |
||||
{ |
||||
excludes.add(url[i]); |
||||
} |
||||
} |
||||
if (StringUtils.isNotEmpty(tempEnabled)) |
||||
{ |
||||
enabled = Boolean.valueOf(tempEnabled); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
||||
throws IOException, ServletException |
||||
{ |
||||
HttpServletRequest req = (HttpServletRequest) request; |
||||
HttpServletResponse resp = (HttpServletResponse) response; |
||||
if (handleExcludeURL(req, resp)) |
||||
{ |
||||
chain.doFilter(request, response); |
||||
return; |
||||
} |
||||
XssHttpServletRequestWrapper xssRequest = new XssHttpServletRequestWrapper((HttpServletRequest) request); |
||||
chain.doFilter(xssRequest, response); |
||||
} |
||||
|
||||
private boolean handleExcludeURL(HttpServletRequest request, HttpServletResponse response) |
||||
{ |
||||
if (!enabled) |
||||
{ |
||||
return true; |
||||
} |
||||
if (excludes == null || excludes.isEmpty()) |
||||
{ |
||||
return false; |
||||
} |
||||
String url = request.getServletPath(); |
||||
for (String pattern : excludes) |
||||
{ |
||||
Pattern p = Pattern.compile("^" + pattern); |
||||
Matcher m = p.matcher(url); |
||||
if (m.find()) |
||||
{ |
||||
return true; |
||||
} |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
@Override |
||||
public void destroy() |
||||
{ |
||||
|
||||
} |
||||
|
||||
} |
@ -0,0 +1,40 @@ |
||||
package com.blockchain.server.base.filter; |
||||
|
||||
import org.jsoup.Jsoup; |
||||
import org.jsoup.safety.Whitelist; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletRequestWrapper; |
||||
|
||||
/** |
||||
* XSS过滤处理 |
||||
*/ |
||||
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper |
||||
{ |
||||
|
||||
/** |
||||
* @param request |
||||
*/ |
||||
public XssHttpServletRequestWrapper(HttpServletRequest request) |
||||
{ |
||||
super(request); |
||||
} |
||||
|
||||
@Override |
||||
public String[] getParameterValues(String name) |
||||
{ |
||||
String[] values = super.getParameterValues(name); |
||||
if (values != null) |
||||
{ |
||||
int length = values.length; |
||||
String[] escapseValues = new String[length]; |
||||
for (int i = 0; i < length; i++) |
||||
{ |
||||
// 防xss攻击和过滤前后空格
|
||||
escapseValues[i] = Jsoup.clean(values[i], Whitelist.relaxed()).trim(); |
||||
} |
||||
return escapseValues; |
||||
} |
||||
return super.getParameterValues(name); |
||||
} |
||||
} |
@ -0,0 +1,34 @@ |
||||
package com.blockchain.server.base.interceptor; |
||||
|
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import com.blockchain.server.base.conf.GlobalExceptionHandle; |
||||
import com.blockchain.server.base.redis.IpInnerCache; |
||||
import org.slf4j.Logger; |
||||
import org.slf4j.LoggerFactory; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
public class InnerInterceptor extends HandlerInterceptorAdapter { |
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandle.class); |
||||
|
||||
@Autowired |
||||
private IpInnerCache innerCache; |
||||
@Override |
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
||||
//经过nginx代理后用户的真实ip
|
||||
String ip = request.getHeader("X-Real-IP"); |
||||
System.out.println("------------内部访问接口IP-----------"+ip); |
||||
String innerIps = innerCache.getIpInner(); |
||||
//若不是内部访问返回链接错误
|
||||
if(innerIps != null && !innerIps.equals("") && innerIps.indexOf(ip) == -1){ |
||||
LOG.info("被拦截ip:"+ ip); |
||||
throw new BaseException(BaseResultEnums.NOT_FOUND); |
||||
} |
||||
return super.preHandle(request, response, handler); |
||||
} |
||||
} |
@ -0,0 +1,20 @@ |
||||
package com.blockchain.server.base.interceptor; |
||||
|
||||
import com.blockchain.common.base.util.SSOHelper; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
public class LoginInterceptor extends HandlerInterceptorAdapter { |
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
|
||||
@Override |
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { |
||||
// SSOHelper.checkUser(redisTemplate, request);
|
||||
return super.preHandle(request, response, handler); |
||||
} |
||||
} |
@ -0,0 +1,46 @@ |
||||
package com.blockchain.server.base.interceptor; |
||||
|
||||
import com.blockchain.common.base.enums.BaseResultEnums; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.core.convert.converter.Converter; |
||||
|
||||
import java.text.SimpleDateFormat; |
||||
import java.util.Date; |
||||
|
||||
public class StringToDateConverter implements Converter<String,Date> { |
||||
private static final String dateFormat = "yyyy-MM-dd HH:mm:ss"; |
||||
private static final String shortDateFormat = "yyyy-MM-dd"; |
||||
private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss"; |
||||
private static final String shortDateFormat2 = "yyyy/MM/dd"; |
||||
@Override |
||||
public Date convert(String source) { |
||||
if (StringUtils.isBlank(source)) { |
||||
return null; |
||||
} |
||||
source = source.trim(); |
||||
try { |
||||
SimpleDateFormat formatter; |
||||
if (source.contains("-")) { |
||||
if (source.contains(":")) { |
||||
formatter = new SimpleDateFormat(dateFormat); |
||||
} else { |
||||
formatter = new SimpleDateFormat(shortDateFormat); |
||||
} |
||||
Date dtDate = formatter.parse(source); |
||||
return dtDate; |
||||
} else if (source.contains("/")) { |
||||
if (source.contains(":")) { |
||||
formatter = new SimpleDateFormat(dateFormat2); |
||||
} else { |
||||
formatter = new SimpleDateFormat(shortDateFormat2); |
||||
} |
||||
Date dtDate = formatter.parse(source); |
||||
return dtDate; |
||||
} |
||||
} catch (Exception e) { |
||||
throw new BaseException(BaseResultEnums.NO_LOGIN); |
||||
} |
||||
throw new RuntimeException(String.format("parser %s to Date fail", source)); |
||||
} |
||||
} |
@ -0,0 +1,28 @@ |
||||
package com.blockchain.server.base.redis; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
/** |
||||
* \* <p>Desciption:</p> |
||||
* \* CreateTime: 2019/2/12 10:08 |
||||
* \* User: XianChaoWei |
||||
* \* Version: V1.0 |
||||
* \ |
||||
*/ |
||||
@Component |
||||
public class IpInnerCache { |
||||
private static final String IP_INNER_CACHE = "ip:inner"; |
||||
|
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
|
||||
public String getIpInner(){ |
||||
if (redisTemplate.hasKey(IP_INNER_CACHE)) {//如果有token信息,更新token的有效时间
|
||||
String ipInner = redisTemplate.opsForValue().get(IP_INNER_CACHE).toString(); |
||||
return ipInner; |
||||
} |
||||
return null; |
||||
} |
||||
} |
@ -0,0 +1,35 @@ |
||||
##使用: |
||||
将依赖加入pom文件 |
||||
``` |
||||
|
||||
<dependency> |
||||
<groupId>com.blockchain</groupId> |
||||
<artifactId>blockchain-server-base</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</dependency> |
||||
|
||||
``` |
||||
|
||||
##注意事项: |
||||
1. 需要将MessagesBundle_default.properties内容拷贝到相应国际化文件,目录位于resource下面的i18n文件夹 |
||||
2. 服务端使用@SpringBootApplication(scanBasePackageClasses={BaseConf.class})将所有配置扫描并交给到spring容器管理 |
||||
3. 如果不需要Xss拦截,可以使用@SpringBootApplication(scanBasePackageClasses={BaseConf.class},exclude={XssConfig.class}) |
||||
4. 每个微服务应该设置自己独立的登录拦截器,指定哪些接口需要登录才能使用,哪些接口不需要 |
||||
5. 对于分布式事务,发起方的service需要加上注解@TxTransaction(isStart = true), |
||||
接收方的service需要实现ITxTransaction,并使用@Transactional |
||||
6. 微服务文件目录固定为 |
||||
``` |
||||
com.blockchain.server.服务名 |
||||
--common |
||||
--conf 登录拦截器、自定义配置等 |
||||
-- |
||||
... |
||||
--controller |
||||
--service |
||||
--feign |
||||
--mapper |
||||
--entity |
||||
--dto |
||||
... |
||||
``` |
||||
|
@ -0,0 +1,5 @@ |
||||
#\u516C\u5171 |
||||
ERROR_PARAMETER_NOTNULL=\u53C2\u6570\u4E0D\u80FD\u4E3A\u7A7A,\u8BF7\u68C0\u67E5\u53C2\u6570 |
||||
RESULT_ERROR_MSG=\u672A\u77E5\u5F02\u5E38 |
||||
LOGIN_INVALID_MSG=\u767B\u5F55\u4FE1\u606F\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 |
||||
SYSTEM_BUSY_MSG=\u7F51\u7EDC\u7E41\u5FD9\uFF01 |
@ -0,0 +1,35 @@ |
||||
<?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>blockchain-server</artifactId> |
||||
<groupId>com.blockchain</groupId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</parent> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
|
||||
<artifactId>blockchain-server-btc</artifactId> |
||||
|
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>com.blockchain</groupId> |
||||
<artifactId>blockchain-server-base</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>com.blockchain</groupId> |
||||
<artifactId>blockchain-common-tx</artifactId> |
||||
<version>1.0-SNAPSHOT</version> |
||||
</dependency> |
||||
</dependencies> |
||||
|
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>org.springframework.boot</groupId> |
||||
<artifactId>spring-boot-maven-plugin</artifactId> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
</project> |
@ -0,0 +1,49 @@ |
||||
package com.blockchain.server.btc; |
||||
|
||||
import com.blockchain.server.base.BaseConf; |
||||
import org.springframework.boot.SpringApplication; |
||||
import org.springframework.boot.autoconfigure.SpringBootApplication; |
||||
import org.springframework.boot.web.servlet.ServletComponentScan; |
||||
import org.springframework.context.annotation.Bean; |
||||
import springfox.documentation.builders.ApiInfoBuilder; |
||||
import springfox.documentation.builders.PathSelectors; |
||||
import springfox.documentation.builders.RequestHandlerSelectors; |
||||
import springfox.documentation.service.ApiInfo; |
||||
import springfox.documentation.spi.DocumentationType; |
||||
import springfox.documentation.spring.web.plugins.Docket; |
||||
|
||||
@ServletComponentScan |
||||
@SpringBootApplication(scanBasePackageClasses = {BaseConf.class, BtcApplication.class}) |
||||
public class BtcApplication { |
||||
public static void main(String[] args) { |
||||
// initSystemConfig();
|
||||
SpringApplication.run(BtcApplication.class, args); |
||||
} |
||||
|
||||
/** |
||||
* 初始化系统配置 |
||||
*/ |
||||
private static void initSystemConfig() { |
||||
System.setProperty("log.root", "ALL,CONSOLE,info,error,DEBUG"); |
||||
System.setProperty("service.id", "dapp-btc-server"); |
||||
} |
||||
|
||||
// @Bean
|
||||
// public Docket createRestApi() {
|
||||
// return new Docket(DocumentationType.SWAGGER_2)
|
||||
// .apiInfo(apiInfo())
|
||||
// .select()
|
||||
// .apis(RequestHandlerSelectors.basePackage("com.blockchain.server.btc.controller"))
|
||||
// .paths(PathSelectors.any())
|
||||
// .build();
|
||||
// }
|
||||
//
|
||||
// private ApiInfo apiInfo() {
|
||||
// return new ApiInfoBuilder()
|
||||
// .title("比特币托管账户系统(dapp-eth-server)RESTful APIs")
|
||||
// .description("")
|
||||
// .termsOfServiceUrl("")
|
||||
// .version("1.0")
|
||||
// .build();
|
||||
// }
|
||||
} |
@ -0,0 +1,32 @@ |
||||
package com.blockchain.server.btc.common.config; |
||||
|
||||
import com.blockchain.server.base.interceptor.LoginInterceptor; |
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry; |
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
||||
|
||||
@Configuration |
||||
public class InterceptorConf implements WebMvcConfigurer { |
||||
@Bean |
||||
public LoginInterceptor loginInterceptor() { |
||||
return new LoginInterceptor(); |
||||
} |
||||
|
||||
@Override |
||||
public void addInterceptors(InterceptorRegistry registry) { |
||||
registry.addInterceptor(loginInterceptor()) |
||||
.addPathPatterns("/**") |
||||
.excludePathPatterns("/inner/**") |
||||
.excludePathPatterns("/webjars/**") |
||||
.excludePathPatterns("/swagger-ui.html") |
||||
.excludePathPatterns("/swagger-resources/**") |
||||
.excludePathPatterns("/v2/api-docs/**"); |
||||
} |
||||
|
||||
@Override |
||||
public void addCorsMappings(CorsRegistry registry) { |
||||
registry.addMapping("/**").allowedOrigins("*"); |
||||
} |
||||
} |
@ -0,0 +1,14 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
/** |
||||
* @author hugq |
||||
* @date 2019/2/16 0016 16:31 |
||||
*/ |
||||
public class BtcAddressConstans { |
||||
|
||||
//redis 存储地址列表的key值,用于解析用户充值区块信息
|
||||
public static final String BTC_ADDRESS_KEY = "btc:adderss:addressSet"; |
||||
//redis 存储地址列表的时间,天数
|
||||
public static final int BTC_ADDRESS_TIME = 30; |
||||
|
||||
} |
@ -0,0 +1,13 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
/** |
||||
* @author hugq |
||||
* @date 2019/2/16 0016 16:31 |
||||
*/ |
||||
public class BtcApplicationConstans { |
||||
|
||||
//钱包类型 币币交易
|
||||
public static final String TYPE_CCT = "CCT"; |
||||
|
||||
|
||||
} |
@ -0,0 +1,20 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
import com.blockchain.common.base.util.DateTimeUtils; |
||||
|
||||
/** |
||||
* @author hugq |
||||
* @date 2019/2/16 0016 16:31 |
||||
*/ |
||||
public class BtcBlockNumberConstans { |
||||
//同步区块高度状态 等待
|
||||
public static final String STATUS_W = "W"; |
||||
//同步区块高度状态 失败
|
||||
public static final String STATUS_N = "N"; |
||||
//同步区块高度状态 成功
|
||||
public static final String STATUS_Y = "Y"; |
||||
|
||||
//查询遗漏区块高度时间差 毫秒数
|
||||
public static final long TIME_DIFFERENCE = 10 * DateTimeUtils.MILLISECOND_OF_MINUTE; |
||||
|
||||
} |
@ -0,0 +1,15 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
/** |
||||
* BTC Config配置常量参数 |
||||
*/ |
||||
public class BtcConfigConstants { |
||||
|
||||
public static final String MODULE_TYPE = "btc"; // 所属于钱包模块
|
||||
public static final int STATUS_DISABLED = 0; // 禁用
|
||||
public static final int STATUS_NORMAL = 1; // 启用
|
||||
|
||||
public static final String GAS_CONFIG = "btc_gas_config_"; |
||||
|
||||
|
||||
} |
@ -0,0 +1,12 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
/** |
||||
* @author hugq |
||||
* @date 2019/2/16 0016 16:31 |
||||
*/ |
||||
public class BtcConstans { |
||||
//btc币种id
|
||||
public static final int BTC_PROPERTY_ID = 0; |
||||
//btc币种名称
|
||||
public static final String BTC_SYMBOL = "BTC"; |
||||
} |
@ -0,0 +1,38 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
/** |
||||
* @author hugq |
||||
* @date 2019/2/16 0016 16:31 |
||||
*/ |
||||
public class BtcTransferConstans { |
||||
|
||||
//交易类型 充值
|
||||
public static final String TYPE_IN = "IN"; |
||||
//交易类型 提现
|
||||
public static final String TYPE_OUT = "OUT"; |
||||
//交易类型 币币交易
|
||||
public static final String TYPE_CCT = "CCT"; |
||||
//交易类型 手续费
|
||||
public static final String TYPE_GAS = "GAS"; |
||||
//交易类型 转内快速转账
|
||||
public static final String TYPE_FAST = "FAST"; |
||||
|
||||
|
||||
//交易状态 失败
|
||||
public static final int STATUS_FILE = 0; |
||||
//交易状态 成功
|
||||
public static final int STATUS_SUCCESS = 1; |
||||
//交易状态 待初审
|
||||
public static final int STATUS_FIRST_TRIAL = 2; |
||||
//交易状态 待复审
|
||||
public static final int STATUS_SECOND_TRIAL = 3; |
||||
//交易状态 待出币
|
||||
public static final int STATUS_STAY_OUT = 4; |
||||
//交易状态 已出币
|
||||
public static final int STATUS_ALREADY_OUT = 5; |
||||
//交易状态 出币失败
|
||||
public static final int STATUS_OUT_FILE = 6; |
||||
//交易状态 审核不通过
|
||||
public static final int STATUS_TRIAL_FILE = 7; |
||||
|
||||
} |
@ -0,0 +1,27 @@ |
||||
package com.blockchain.server.btc.common.constants; |
||||
|
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.annotation.PostConstruct; |
||||
|
||||
@Component |
||||
public class UsdtConstans { |
||||
|
||||
//注入配置的usdt币种id,避免忘记修改
|
||||
@Value("${btc.usdt_property_id}") |
||||
private Integer USDT_PROPERTY_ID_CONF; |
||||
|
||||
@PostConstruct |
||||
public void init() { |
||||
this.USDT_PROPERTY_ID = USDT_PROPERTY_ID_CONF; |
||||
} |
||||
|
||||
|
||||
//usdt币种id 默认正式网31
|
||||
public static int USDT_PROPERTY_ID = 31; |
||||
|
||||
//usdt币种名称
|
||||
public static final String USDT_SYMBOL = "USDT"; |
||||
|
||||
} |
@ -0,0 +1,73 @@ |
||||
package com.blockchain.server.btc.common.enums; |
||||
|
||||
public enum BtcEnums { |
||||
ADDRESS_ERROR(7000, "请输入有效的地址", "Please enter a valid address.", "請輸入有效的地址"), |
||||
AMOUNT_NULL(7001, "请输入数量", "Please input quantity.", "請輸入數量"), |
||||
SENDTOADDRESS_ERROR(7002, "交易失败", "Transaction failure.", "交易失敗"), |
||||
GET_NEW_ADDRESS_ERROR(7003, "生成地址失败", "Request success", "生成地址失敗"), |
||||
LIST_UNSPENT_ERROR(7004, "获取UTXO失败", "Failed to get UTXO", "獲取UTXO失敗"), |
||||
CREATE_WALLET_ERROR(7005, "创建钱包失败", "Failed to create wallet.", "創建錢包失敗"), |
||||
PARSE_TRANSFER_IN_ERROR(7006, "解析区块充值信息到数据库失败", "Failed to parse block recharge information to database.", "解析區塊充值信息到數據庫失敗"), |
||||
INSERT_BLOCKNUMBER_ERROR(7007, "插入同步区块号失败", "Failed to insert synchronized block number.", "插入同步區塊號失敗"), |
||||
WITHDRAW_ERROR(7008, "提现失败", "Failed to withdrawal.", "提現失敗"), |
||||
FREEBALANCE_NOT_ENOUGH(7009, "钱包可用余额不足", "Insufficient balance available in wallet.", "錢包可用餘額不足"), |
||||
INSERT_AUDITING_ERROR(7010, "插入审核记录失败", "Failed to insert audit record.", "插入審覈記錄失敗"), |
||||
INSERT_WALLET_OUT_ERROR(7011, "插入提现资金钱包失败", "Failed to insert withdrawal fund wallet.", "插入提現資金錢包失敗"), |
||||
UPDATE_BLOCK_NUMBER_STATUS_ERROR(7012, "修改同步区块状态失败", "Failed to modify synchronized block state.", "修改同步區塊狀態失敗"), |
||||
TRANSFER_ERROR(7013, "交易失败", "Failed to transact.", "交易失敗"), |
||||
BALANCE_NOT_ENOUGH(7014, "钱包余额不足", "Insufficient balance of wallet.", "錢包餘額不足"), |
||||
INEXISTENCE_TOKENNAME(7015, "不识别该币种名称", "The currency name is not recognized.", "不識別該幣種名稱"), |
||||
INEXISTENCE_TOKENID(7016, "不识别该币种类型", "The currency type is not recognized.", "不識別該幣種類型"), |
||||
INEXISTENCE_WALLETTYPE(7017, "该钱包类型不存在", "The wallet type does not exist.", "該錢包類型不存在"), |
||||
LOW_WITHDRAW_AMOUNT_ERROR(7018, "提现数量过低", "The withdrawal amount is too low.", "提現數量過低"), |
||||
NO_WALLET_ERROR(7019, "钱包信息未找到", "Wallet information not found", "錢包信息未找到"), |
||||
SERVER_IS_TOO_BUSY(15000, "服务器繁忙,请稍后重试", "The server is busy, please try again later", "服務器繁忙,請稍後重試"), |
||||
INEXISTENCE_WALLET(7017, "该钱包不存在", "The wallet does not exist.", "該錢包不存在"), |
||||
|
||||
; |
||||
|
||||
private int code; |
||||
private String cnmsg; |
||||
private String enMsg; |
||||
private String hkmsg; |
||||
|
||||
BtcEnums(int code, String cnmsg, String enMsg, String hkmsg) { |
||||
this.code = code; |
||||
this.cnmsg = cnmsg; |
||||
this.enMsg = enMsg; |
||||
this.hkmsg = hkmsg; |
||||
} |
||||
|
||||
public int getCode() { |
||||
return code; |
||||
} |
||||
|
||||
public void setCode(int code) { |
||||
this.code = code; |
||||
} |
||||
|
||||
public String getHkmsg() { |
||||
return hkmsg; |
||||
} |
||||
|
||||
public void setHkmsg(String hkmsg) { |
||||
this.hkmsg = hkmsg; |
||||
} |
||||
|
||||
public String getEnMsg() { |
||||
return enMsg; |
||||
} |
||||
|
||||
public void setEnMsg(String enMsg) { |
||||
this.enMsg = enMsg; |
||||
} |
||||
|
||||
public String getCnmsg() { |
||||
return cnmsg; |
||||
} |
||||
|
||||
public void setCnmsg(String cnmsg) { |
||||
this.cnmsg = cnmsg; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,40 @@ |
||||
package com.blockchain.server.btc.common.exception; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.exception.BaseException; |
||||
import com.blockchain.common.base.util.HttpRequestUtil; |
||||
import com.blockchain.server.btc.common.enums.BtcEnums; |
||||
import org.springframework.web.context.request.RequestContextHolder; |
||||
import org.springframework.web.context.request.ServletRequestAttributes; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
public class BtcException extends BaseException { |
||||
|
||||
public BtcException(BtcEnums rs) { |
||||
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); |
||||
//可能是定时器调用,避免获取request空指针
|
||||
if (servletRequestAttributes == null) { |
||||
this.code = rs.getCode(); |
||||
this.msg = rs.getCnmsg(); |
||||
} else { |
||||
HttpServletRequest request = servletRequestAttributes.getRequest(); |
||||
String userLocale = HttpRequestUtil.getUserLocale(request); |
||||
String msg = ""; |
||||
switch (userLocale) { |
||||
case BaseConstant.USER_LOCALE_EN_US: |
||||
msg = rs.getEnMsg(); |
||||
break; |
||||
case BaseConstant.USER_LOCALE_ZH_HK: |
||||
msg = rs.getHkmsg(); |
||||
break; |
||||
default: |
||||
msg = rs.getCnmsg(); |
||||
break; |
||||
} |
||||
this.code = rs.getCode(); |
||||
this.msg = msg; |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,53 @@ |
||||
package com.blockchain.server.btc.common.util; |
||||
|
||||
import com.blockchain.server.btc.common.constants.BtcAddressConstans; |
||||
import com.blockchain.server.btc.service.BtcWalletService; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import java.util.Set; |
||||
|
||||
@Component |
||||
public class BtcAddressSetRedisUtils { |
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
|
||||
@Autowired |
||||
private BtcWalletService btcWalletService; |
||||
|
||||
/** |
||||
* 保存地址集合到redis |
||||
* |
||||
* @param address 新增地址 |
||||
*/ |
||||
public void insert(String address) { |
||||
redisTemplate.opsForSet().add(BtcAddressConstans.BTC_ADDRESS_KEY, address); |
||||
} |
||||
|
||||
/** |
||||
* 从redis中获取地址集合 |
||||
* |
||||
* @return |
||||
*/ |
||||
public Set<String> get() { |
||||
return redisTemplate.opsForSet().members(BtcAddressConstans.BTC_ADDRESS_KEY); |
||||
} |
||||
|
||||
/** |
||||
* 判断缓存中是否存在该地址 |
||||
* |
||||
* @param addr 地址 |
||||
* @return |
||||
*/ |
||||
public boolean isExistsAddr(String addr) { |
||||
Set<String> addressSet = get(); |
||||
if (addressSet == null || addressSet.size() == 0) { |
||||
addressSet = btcWalletService.getAllWalletAddr(); |
||||
redisTemplate.opsForSet().add(BtcAddressConstans.BTC_ADDRESS_KEY, addressSet.toArray()); |
||||
} |
||||
|
||||
return addressSet.contains(addr); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,43 @@ |
||||
package com.blockchain.server.btc.common.util; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
@Component |
||||
public class BtcBlockRedisUtils { |
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
|
||||
private static final String ETH_BLOCKCHAIN_OPT_HASH = "btc:blockchain:opt:block"; |
||||
|
||||
/** |
||||
* 根据区块高度,获取爬取的次数 |
||||
* |
||||
* @param blockHeight 区块高度 |
||||
* @return |
||||
*/ |
||||
public int getBlockOptMapCount(int blockHeight) { |
||||
Integer val = (Integer) redisTemplate.opsForHash().get(ETH_BLOCKCHAIN_OPT_HASH, blockHeight); |
||||
return val != null ? val : 0; |
||||
} |
||||
|
||||
/** |
||||
* 爬取次数加1 |
||||
* |
||||
* @param blockHeight 区块高度 |
||||
*/ |
||||
public void incrementBlockOptMapCount(int blockHeight) { |
||||
redisTemplate.opsForHash().increment(ETH_BLOCKCHAIN_OPT_HASH, blockHeight, 1); |
||||
} |
||||
|
||||
/** |
||||
* 移除区块的爬取记录 |
||||
* |
||||
* @param blockHeight 区块高度 |
||||
*/ |
||||
public void delBlockOptMapCount(int blockHeight) { |
||||
redisTemplate.opsForHash().delete(ETH_BLOCKCHAIN_OPT_HASH, blockHeight); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,60 @@ |
||||
package com.blockchain.server.btc.common.util; |
||||
|
||||
import org.apache.commons.codec.binary.Base64; |
||||
|
||||
import javax.crypto.Cipher; |
||||
import java.security.KeyFactory; |
||||
import java.security.PrivateKey; |
||||
import java.security.PublicKey; |
||||
import java.security.spec.PKCS8EncodedKeySpec; |
||||
import java.security.spec.X509EncodedKeySpec; |
||||
|
||||
/** |
||||
* @author hugq |
||||
* @date 2019/2/21 10:17 |
||||
*/ |
||||
public class BtcRASUtils { |
||||
//非对称密钥算法
|
||||
private static final String KEY_ALGORITHM = "RSA"; |
||||
|
||||
//公钥
|
||||
private static final byte[] PUBLIC_KEY = {48, -127, -97, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 3, -127, -115, 0, 48, -127, -119, 2, -127, -127, 0, -128, 48, -25, 69, -64, -57, -59, -64, -116, -5, -4, -26, -5, 109, 17, 59, 68, -69, -16, -110, 19, -21, -78, 25, 77, -40, 18, 77, 2, 70, -45, 15, 112, 57, 111, 14, 78, -69, 18, -115, 21, 9, -38, 126, -107, -116, -124, -95, -116, 6, 18, 57, -73, -25, -9, 46, 69, 1, 127, -27, -92, 2, -119, 106, -33, -78, -35, -26, 72, -65, 116, 61, -53, 85, 94, 68, -84, -121, 55, -68, 77, -128, 6, -99, 81, -5, 80, 52, 68, 53, -27, 79, -14, 37, 41, -18, 70, 96, -65, -32, -82, 75, -23, -77, -39, -36, -46, 120, 7, 67, 101, 107, 58, 97, 66, 72, -52, -128, -62, 39, -121, -47, -73, 73, -100, 49, 9, 113, 2, 3, 1, 0, 1}; |
||||
|
||||
//私钥
|
||||
private static final byte[] PRIVATE_KEY = {48, -126, 2, 118, 2, 1, 0, 48, 13, 6, 9, 42, -122, 72, -122, -9, 13, 1, 1, 1, 5, 0, 4, -126, 2, 96, 48, -126, 2, 92, 2, 1, 0, 2, -127, -127, 0, -128, 48, -25, 69, -64, -57, -59, -64, -116, -5, -4, -26, -5, 109, 17, 59, 68, -69, -16, -110, 19, -21, -78, 25, 77, -40, 18, 77, 2, 70, -45, 15, 112, 57, 111, 14, 78, -69, 18, -115, 21, 9, -38, 126, -107, -116, -124, -95, -116, 6, 18, 57, -73, -25, -9, 46, 69, 1, 127, -27, -92, 2, -119, 106, -33, -78, -35, -26, 72, -65, 116, 61, -53, 85, 94, 68, -84, -121, 55, -68, 77, -128, 6, -99, 81, -5, 80, 52, 68, 53, -27, 79, -14, 37, 41, -18, 70, 96, -65, -32, -82, 75, -23, -77, -39, -36, -46, 120, 7, 67, 101, 107, 58, 97, 66, 72, -52, -128, -62, 39, -121, -47, -73, 73, -100, 49, 9, 113, 2, 3, 1, 0, 1, 2, -127, -128, 103, -35, 55, -59, -64, -119, 28, -91, 2, -106, 57, 55, 61, -120, 5, 106, 44, 42, -54, -92, -47, 23, 43, 90, 109, 68, 32, -81, -36, -92, 93, -26, 40, 91, -96, -85, -53, 6, -81, -27, 55, -94, -96, 49, -24, 33, -50, 100, -59, -5, 53, 81, 38, -68, -1, -3, -79, 83, -95, -71, 2, -58, 59, 103, -13, -78, -15, 56, 113, 53, -107, -98, 6, 54, -95, -110, -115, 88, 2, -122, -111, 9, 29, 22, -78, -21, 105, -95, -74, -62, 109, -31, -48, -75, 101, 112, 103, 26, 11, -126, 97, 48, 115, -74, 47, 122, -14, 97, -55, 77, 49, 7, -105, -87, 58, 21, -117, 98, -28, 27, -106, 113, -30, -28, 45, -101, -109, 1, 2, 65, 0, -7, -37, 63, 25, -106, 28, 88, 14, -22, -47, -26, -117, 4, 55, -10, 37, -73, 111, 75, 24, -123, 104, 42, -20, -46, -95, -119, -41, -82, -85, -11, -27, 41, -8, 38, 22, 112, -51, 35, 112, 23, -66, 4, -55, -6, 33, -121, -98, 35, 2, -64, -79, 118, -85, -83, -33, -103, -107, -33, 127, -52, -115, 93, 25, 2, 65, 0, -125, 87, -47, -128, 76, -6, -66, 113, -107, 27, -58, -46, -15, -54, 59, -74, -98, -95, 16, -43, 109, 81, -79, 26, -57, 120, -82, 95, 66, 47, 105, 49, -92, -28, 61, 81, -60, 115, -18, -84, 8, 99, 25, -123, -109, 46, -48, 115, -37, -13, 56, 6, -9, 36, -36, 112, -42, -8, 62, -87, 21, 70, -62, 25, 2, 65, 0, -16, -26, -89, 76, 48, 35, 91, -13, -26, 12, 67, 80, 61, -35, 7, 3, 14, 125, -53, -43, -12, -86, -98, -40, 127, -83, 40, -114, 63, -25, -92, -54, 51, 81, 2, -56, 24, 50, 113, -68, -99, -25, -92, 14, 105, -112, -14, -123, 82, 20, 81, 93, -55, -95, 117, -97, 101, 33, -49, -64, 20, -91, 39, -31, 2, 64, 7, 23, 44, -106, 50, -111, -82, -54, 78, -12, 106, -19, 100, 100, 56, -119, 9, 83, 68, -89, 96, -7, 114, 8, 50, 16, -113, -55, 80, -73, 98, -124, 109, -108, 108, -61, 7, 74, 2, -18, -126, -99, 102, -7, 81, 18, -53, -22, 21, 75, -78, 16, -98, 50, -3, 59, -110, 63, 96, -110, -100, 53, 111, -79, 2, 64, 80, -113, -19, 28, -46, -110, -75, 123, -29, -94, -19, -28, -64, -124, 87, 5, -4, 125, 35, -68, 68, -4, -60, -38, 123, -28, -34, -1, 1, 52, -11, 19, -32, -24, 83, 119, -4, 66, -93, -43, -3, 105, -106, 22, -39, -55, 116, 91, -124, 39, -106, 37, -83, -39, 26, 118, 78, -87, 22, 76, 12, -110, 112, 77}; |
||||
|
||||
/** |
||||
* 加密数据 |
||||
* |
||||
* @param encrypt 待加密数据 |
||||
* @return |
||||
*/ |
||||
public static String encrypt(String encrypt) throws Exception { |
||||
//公钥加密
|
||||
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(PUBLIC_KEY); |
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); |
||||
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); |
||||
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); |
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey); |
||||
byte[] result = cipher.doFinal(encrypt.getBytes()); |
||||
return Base64.encodeBase64String(result); |
||||
} |
||||
|
||||
/** |
||||
* 解密数据 |
||||
* |
||||
* @param decrypt 待解密数据 |
||||
* @return |
||||
*/ |
||||
public static String decrypt(String decrypt) throws Exception { |
||||
//私钥解密
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(PRIVATE_KEY); |
||||
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); |
||||
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); |
||||
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM); |
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey); |
||||
byte[] result = cipher.doFinal(Base64.decodeBase64(decrypt)); |
||||
return new String(result); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,22 @@ |
||||
package com.blockchain.server.btc.common.util; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.common.base.exception.RPCException; |
||||
|
||||
/*** |
||||
* 校验ethFegin返回值 |
||||
*/ |
||||
public class CheckEthFeginResult { |
||||
|
||||
/*** |
||||
* 检查isPassword接口返回值 |
||||
* @param resultDTO isPassword接口返回值 |
||||
*/ |
||||
public static void checkIsPassword(ResultDTO resultDTO) { |
||||
if (BaseConstant.REQUEST_SUCCESS != resultDTO.getCode()) { |
||||
throw new RPCException(resultDTO); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,35 @@ |
||||
package com.blockchain.server.btc.controller; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.server.btc.common.constants.BtcConstans; |
||||
import com.blockchain.server.btc.controller.api.BtcTokenApi; |
||||
import com.blockchain.server.btc.service.BtcTokenService; |
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import io.swagger.annotations.ApiParam; |
||||
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; |
||||
|
||||
@Api(BtcTokenApi.MARKET_CONTROLLER_API) |
||||
@RestController |
||||
@RequestMapping("/walletToken") |
||||
public class BtcTokenController { |
||||
@Autowired |
||||
private BtcTokenService btcTokenService; |
||||
|
||||
@ApiOperation(value = BtcTokenApi.ListToken.METHOD_API_NAME, notes = BtcTokenApi.ListToken.METHOD_API_NOTE) |
||||
@GetMapping("/listToken") |
||||
public ResultDTO listToken() { |
||||
return ResultDTO.requstSuccess(btcTokenService.listToken()); |
||||
} |
||||
|
||||
@ApiOperation(value = BtcTokenApi.GetToken.METHOD_API_NAME, notes = BtcTokenApi.GetToken.METHOD_API_NOTE) |
||||
@GetMapping("/getToken") |
||||
public ResultDTO getToken(@ApiParam(BtcTokenApi.GetToken.TOKENID) @RequestParam(value = "tokenId", defaultValue = BtcConstans.BTC_PROPERTY_ID + "") Integer tokenId) { |
||||
return ResultDTO.requstSuccess(btcTokenService.selectTokenById(tokenId)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,54 @@ |
||||
package com.blockchain.server.btc.controller; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.common.base.util.SSOHelper; |
||||
import com.blockchain.server.btc.common.constants.BtcApplicationConstans; |
||||
import com.blockchain.server.btc.controller.api.BtcWalletApi; |
||||
import com.blockchain.server.btc.service.BtcWalletService; |
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import io.swagger.annotations.ApiParam; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
@Api(BtcWalletApi.MARKET_CONTROLLER_API) |
||||
@RestController |
||||
@RequestMapping("/wallet") |
||||
public class BtcWalletController { |
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
|
||||
@Autowired |
||||
private BtcWalletService btcWalletService; |
||||
|
||||
|
||||
@ApiOperation(value = BtcWalletApi.GetWallet.METHOD_API_NAME, notes = BtcWalletApi.GetWallet.METHOD_API_NOTE) |
||||
@GetMapping("/getWallet") |
||||
public ResultDTO getWallet(HttpServletRequest request, |
||||
@ApiParam(BtcWalletApi.GetWallet.WALLETTYPE) @RequestParam(value = "walletType", defaultValue = BtcApplicationConstans.TYPE_CCT) String walletType, |
||||
@ApiParam(BtcWalletApi.GetWallet.TOKENID) @RequestParam("tokenId") Integer tokenId) { |
||||
String userOpenId = SSOHelper.getUserId(redisTemplate, request); |
||||
return ResultDTO.requstSuccess(btcWalletService.selectByUserOpenId(userOpenId, tokenId, walletType)); |
||||
} |
||||
|
||||
@ApiOperation(value = BtcWalletApi.GetWallets.METHOD_API_NAME, notes = BtcWalletApi.GetWallets.METHOD_API_NOTE) |
||||
@GetMapping("/getWallets") |
||||
public ResultDTO getWallets(@ApiParam(BtcWalletApi.GetWallets.WALLETTYPE) @RequestParam(name = "walletType", defaultValue = BtcApplicationConstans.TYPE_CCT) String walletType, |
||||
HttpServletRequest request) { |
||||
String userId = SSOHelper.getUserId(redisTemplate, request); |
||||
return ResultDTO.requstSuccess(btcWalletService.selectAllByUserOpenId(userId, walletType)); |
||||
} |
||||
@ApiOperation(value = BtcWalletApi.Transfer.METHOD_API_NAME, notes = BtcWalletApi.Transfer.METHOD_API_NOTE) |
||||
@PostMapping("/transfer") |
||||
public ResultDTO handleTransfer(HttpServletRequest request, |
||||
@ApiParam(BtcWalletApi.Transfer.METHOD_API_FROMTYPE) @RequestParam("fromType") String fromType, |
||||
@ApiParam(BtcWalletApi.Transfer.METHOD_API_TOTYPE) @RequestParam("toType") String toType, |
||||
@ApiParam(BtcWalletApi.Transfer.METHOD_API_COINNAME) @RequestParam("coinName") String coinName, |
||||
@ApiParam(BtcWalletApi.Transfer.METHOD_API_AMOUNT) @RequestParam("amount") Double amount) { |
||||
String userOpenId = SSOHelper.getUserId(redisTemplate, request); |
||||
return ResultDTO.requstSuccess(btcWalletService.handleTransfer(userOpenId,fromType, toType, coinName, amount)); |
||||
} |
||||
} |
@ -0,0 +1,72 @@ |
||||
package com.blockchain.server.btc.controller; |
||||
|
||||
import com.blockchain.common.base.constant.BaseConstant; |
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.common.base.util.SSOHelper; |
||||
import com.blockchain.server.base.controller.BaseController; |
||||
import com.blockchain.server.btc.common.constants.BtcApplicationConstans; |
||||
import com.blockchain.server.btc.controller.api.BtcWalletTransferApi; |
||||
import com.blockchain.server.btc.dto.BtcWalletTransferDTO; |
||||
import com.blockchain.server.btc.service.BtcWalletTransferService; |
||||
import com.github.pagehelper.PageHelper; |
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import io.swagger.annotations.ApiParam; |
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.data.redis.core.RedisTemplate; |
||||
import org.springframework.web.bind.annotation.*; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
import java.util.List; |
||||
|
||||
@Api(BtcWalletTransferApi.MARKET_CONTROLLER_API) |
||||
@RestController |
||||
@RequestMapping("/walletTransfer") |
||||
public class BtcWalletTransferController extends BaseController { |
||||
@Autowired |
||||
private RedisTemplate redisTemplate; |
||||
|
||||
@Autowired |
||||
private BtcWalletTransferService btcWalletTransferService; |
||||
|
||||
|
||||
@ApiOperation(value = BtcWalletTransferApi.GetTransfer.METHOD_API_NAME, notes = BtcWalletTransferApi.GetTransfer.METHOD_API_NOTE) |
||||
@GetMapping("/getTransfer") |
||||
public ResultDTO getTransfer(HttpServletRequest request, |
||||
@ApiParam(BtcWalletTransferApi.PAGENUM) @RequestParam(name = "pageNum", defaultValue = BaseConstant.PAGE_DEFAULT_INDEX) Integer pageNum, |
||||
@ApiParam(BtcWalletTransferApi.PAGESIZE) @RequestParam(name = "pageSize", defaultValue = BaseConstant.PAGE_DEFAULT_SIZE) Integer pageSize, |
||||
@ApiParam(BtcWalletTransferApi.GetTransfer.TOKENID) @RequestParam("tokenId") Integer tokenId, |
||||
@ApiParam(BtcWalletTransferApi.GetTransfer.WALLET_TYPE) @RequestParam(value = "walletType", defaultValue = BtcApplicationConstans.TYPE_CCT) String walletType) { |
||||
String userOpenId = SSOHelper.getUserId(redisTemplate, request); |
||||
//分页查询记录
|
||||
PageHelper.startPage(pageNum, pageSize); |
||||
return ResultDTO.requstSuccess(btcWalletTransferService.selectTransfer(userOpenId, tokenId, walletType)); |
||||
} |
||||
|
||||
@ApiOperation(value = BtcWalletTransferApi.pcGetTransfer.METHOD_API_NAME, notes = BtcWalletTransferApi.pcGetTransfer.METHOD_API_NOTE) |
||||
@GetMapping("/pcGetTransfer") |
||||
public ResultDTO pcGetTransfer(HttpServletRequest request, |
||||
@ApiParam(BtcWalletTransferApi.PAGENUM) @RequestParam(name = "pageNum", defaultValue = BaseConstant.PAGE_DEFAULT_INDEX) Integer pageNum, |
||||
@ApiParam(BtcWalletTransferApi.PAGESIZE) @RequestParam(name = "pageSize", defaultValue = BaseConstant.PAGE_DEFAULT_SIZE) Integer pageSize, |
||||
@ApiParam(BtcWalletTransferApi.pcGetTransfer.TOKENID) @RequestParam("tokenId") Integer tokenId, |
||||
@ApiParam(BtcWalletTransferApi.pcGetTransfer.WALLET_TYPE) @RequestParam(value = "walletType", defaultValue = BtcApplicationConstans.TYPE_CCT) String walletType) { |
||||
String userOpenId = SSOHelper.getUserId(redisTemplate, request); |
||||
//分页查询记录
|
||||
PageHelper.startPage(pageNum, pageSize); |
||||
List<BtcWalletTransferDTO> list = btcWalletTransferService.selectTransfer(userOpenId, tokenId, walletType); |
||||
return generatePage(list); |
||||
} |
||||
|
||||
@ApiOperation(value = BtcWalletTransferApi.Withdraw.METHOD_API_NAME, notes = BtcWalletTransferApi.Withdraw.METHOD_API_NOTE) |
||||
@PostMapping("/withdraw") |
||||
public ResultDTO withdraw(HttpServletRequest request, |
||||
@ApiParam(BtcWalletTransferApi.Withdraw.TOADDR) @RequestParam("toAddr") String toAddr, |
||||
@ApiParam(BtcWalletTransferApi.Withdraw.PASSWORD) @RequestParam("password") String password, |
||||
@ApiParam(BtcWalletTransferApi.Withdraw.AMOUNT) @RequestParam("amount") Double amount, |
||||
@ApiParam(BtcWalletTransferApi.Withdraw.TOKENID) @RequestParam("tokenId") Integer tokenId, |
||||
@ApiParam(BtcWalletTransferApi.Withdraw.WALLET_TYPE) @RequestParam(value = "walletType", defaultValue = BtcApplicationConstans.TYPE_CCT) String walletType) { |
||||
String userOpenId = SSOHelper.getUserId(redisTemplate, request); |
||||
return ResultDTO.requstSuccess(btcWalletTransferService.handleWithdraw(userOpenId, password, toAddr, tokenId, amount, walletType)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,29 @@ |
||||
package com.blockchain.server.btc.controller; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import com.blockchain.server.btc.common.constants.BtcConstans; |
||||
import com.blockchain.server.btc.controller.api.ConfigWalletParamApi; |
||||
import com.blockchain.server.btc.service.ConfigWalletParamService; |
||||
import io.swagger.annotations.Api; |
||||
import io.swagger.annotations.ApiOperation; |
||||
import io.swagger.annotations.ApiParam; |
||||
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; |
||||
|
||||
@Api(ConfigWalletParamApi.MARKET_CONTROLLER_API) |
||||
@RestController |
||||
@RequestMapping("/walletParam") |
||||
public class ConfigWalletParamController { |
||||
@Autowired |
||||
private ConfigWalletParamService walletParamService; |
||||
|
||||
@ApiOperation(value = ConfigWalletParamApi.GetGasConfig.METHOD_API_NAME, notes = ConfigWalletParamApi.GetGasConfig.METHOD_API_NOTE) |
||||
@GetMapping("/getGasConfig") |
||||
public ResultDTO getGasConfig(@ApiParam(ConfigWalletParamApi.GetGasConfig.TOKENSYMBOL) @RequestParam(value = "tokenSymbol", defaultValue = BtcConstans.BTC_SYMBOL) String tokenSymbol) { |
||||
return ResultDTO.requstSuccess(walletParamService.getGasConfig(tokenSymbol)); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,17 @@ |
||||
package com.blockchain.server.btc.controller.api; |
||||
|
||||
public class BtcTokenApi { |
||||
public static final String MARKET_CONTROLLER_API = "比特币币种控制器"; |
||||
|
||||
public static class ListToken { |
||||
public static final String METHOD_API_NAME = "获取币种列表信息"; |
||||
public static final String METHOD_API_NOTE = "获取币种列表信息"; |
||||
} |
||||
|
||||
public static class GetToken { |
||||
public static final String METHOD_API_NAME = "获取币种,根据tokenid"; |
||||
public static final String METHOD_API_NOTE = "获取币种,根据tokenid"; |
||||
public static final String TOKENID = "币种id"; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,29 @@ |
||||
package com.blockchain.server.btc.controller.api; |
||||
|
||||
public class BtcWalletApi { |
||||
public static final String MARKET_CONTROLLER_API = "比特币钱包控制器"; |
||||
|
||||
public static final String PAGENUM = "当前页数"; |
||||
public static final String PAGESIZE = "页数展示条数"; |
||||
|
||||
public static class GetWallet { |
||||
public static final String METHOD_API_NAME = "获取用户钱包"; |
||||
public static final String METHOD_API_NOTE = "获取用户钱包"; |
||||
public static final String TOKENID = "币种id"; |
||||
public static final String WALLETTYPE = "应用类型"; |
||||
} |
||||
|
||||
public static class GetWallets { |
||||
public static final String METHOD_API_NAME = "获取用户钱包所有币种信息"; |
||||
public static final String METHOD_API_NOTE = "获取用户钱包所有币种信息"; |
||||
public static final String WALLETTYPE = "应用类型"; |
||||
} |
||||
public static class Transfer { |
||||
public static final String METHOD_API_NAME = "钱包划转"; |
||||
public static final String METHOD_API_NOTE = "钱包划转"; |
||||
public static final String METHOD_API_FROMTYPE = "支付方钱包类型"; |
||||
public static final String METHOD_API_TOTYPE = "收款钱包类型"; |
||||
public static final String METHOD_API_COINNAME = "划转币种的名称"; |
||||
public static final String METHOD_API_AMOUNT = "金额"; |
||||
} |
||||
} |
@ -0,0 +1,33 @@ |
||||
package com.blockchain.server.btc.controller.api; |
||||
|
||||
public class BtcWalletTransferApi { |
||||
public static final String MARKET_CONTROLLER_API = "比特币交易控制器"; |
||||
|
||||
public static final String PAGENUM = "当前页数"; |
||||
public static final String PAGESIZE = "页数展示条数"; |
||||
|
||||
public static class GetTransfer { |
||||
public static final String METHOD_API_NAME = "app端查询所有交易记录"; |
||||
public static final String METHOD_API_NOTE = "app端查询所有交易记录"; |
||||
public static final String TOKENID = "币种id"; |
||||
public static final String WALLET_TYPE = "应用类型"; |
||||
} |
||||
|
||||
public static class pcGetTransfer { |
||||
public static final String METHOD_API_NAME = "pc端查询所有交易记录"; |
||||
public static final String METHOD_API_NOTE = "pc端查询所有交易记录"; |
||||
public static final String TOKENID = "币种id"; |
||||
public static final String WALLET_TYPE = "应用类型"; |
||||
} |
||||
|
||||
public static class Withdraw { |
||||
public static final String METHOD_API_NAME = "提现"; |
||||
public static final String METHOD_API_NOTE = "提现"; |
||||
public static final String TOKENID = "币种id"; |
||||
public static final String WALLET_TYPE = "应用类型"; |
||||
public static final String TOADDR = "接收地址"; |
||||
public static final String AMOUNT = "提现数量"; |
||||
public static final String PASSWORD = "加密密码"; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,12 @@ |
||||
package com.blockchain.server.btc.controller.api; |
||||
|
||||
public class ConfigWalletParamApi { |
||||
public static final String MARKET_CONTROLLER_API = "钱包配置表控制器"; |
||||
|
||||
public static class GetGasConfig { |
||||
public static final String METHOD_API_NAME = "获取币种手续费配置"; |
||||
public static final String METHOD_API_NOTE = "获取币种手续费配置"; |
||||
public static final String TOKENSYMBOL = "币种名称"; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,21 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcApplicationDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcApplicationDTO extends BaseModel { |
||||
private String appId; |
||||
private String appName; |
||||
|
||||
} |
@ -0,0 +1,23 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcBlockNumberDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcBlockNumberDTO extends BaseModel { |
||||
private Integer blockNumber; |
||||
private java.util.Date createTime; |
||||
private java.util.Date updateTime; |
||||
private String status; |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcTokenDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcTokenDTO extends BaseModel { |
||||
private Integer tokenId; |
||||
private String tokenSymbol; |
||||
private java.util.Date issueTime; |
||||
private String totalSupply; |
||||
private String totalCirculation; |
||||
private String descr; |
||||
|
||||
} |
@ -0,0 +1,25 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcTransferAuditingDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcTransferAuditingDTO extends BaseModel { |
||||
private String id; |
||||
private String sysUserId; |
||||
private String ipAddr; |
||||
private String transferId; |
||||
private String transferStatus; |
||||
private java.util.Date createTime; |
||||
|
||||
} |
@ -0,0 +1,29 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcWalletDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletDTO extends BaseModel { |
||||
private String addr; |
||||
private Integer tokenId; |
||||
private String userOpenId; |
||||
private String tokenSymbol; |
||||
private Double balance; |
||||
private Double freeBalance; |
||||
private Double freezeBalance; |
||||
private java.util.Date createTime; |
||||
private java.util.Date updateTime; |
||||
private String walletType; |
||||
|
||||
} |
@ -0,0 +1,21 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcWalletKeyDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletKeyDTO extends BaseModel { |
||||
private String addr; |
||||
private String privateKey; |
||||
|
||||
} |
@ -0,0 +1,26 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcWalletOutDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletOutDTO extends BaseModel { |
||||
private String id; |
||||
private String addr; |
||||
private Integer tokenId; |
||||
private String tokenSymbol; |
||||
private String privateKey; |
||||
private String password; |
||||
private String remark; |
||||
|
||||
} |
@ -0,0 +1,35 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* BtcWalletTransferDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletTransferDTO extends BaseModel { |
||||
private String id; |
||||
private String hash; |
||||
private String fromAddr; |
||||
private String toAddr; |
||||
private Double amount; |
||||
private Integer tokenId; |
||||
private String tokenSymbol; |
||||
private Double gasPrice; |
||||
private String gasTokenType; |
||||
private String gasTokenName; |
||||
private String gasTokenSymbol; |
||||
private String transferType; |
||||
private Integer status; |
||||
private String remark; |
||||
private java.util.Date createTime; |
||||
private java.util.Date updateTime; |
||||
|
||||
} |
@ -0,0 +1,24 @@ |
||||
package com.blockchain.server.btc.dto; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
/** |
||||
* EthApplication 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:44:06 |
||||
*/ |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class ConfigWalletParamDTO extends BaseModel { |
||||
private String id; |
||||
private String moduleType; |
||||
private String paramName; |
||||
private String paramValue; |
||||
private String paramDescr; |
||||
private Integer status; |
||||
} |
@ -0,0 +1,29 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcApplicationDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_application") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcApplication extends BaseModel { |
||||
@Id |
||||
@Column(name = "app_id") |
||||
private String appId; |
||||
@Column(name = "app_name") |
||||
private String appName; |
||||
|
||||
} |
@ -0,0 +1,33 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcBlockNumberDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_block_number") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcBlockNumber extends BaseModel { |
||||
@Id |
||||
@Column(name = "block_number") |
||||
private Integer blockNumber; |
||||
@Column(name = "create_time") |
||||
private java.util.Date createTime; |
||||
@Column(name = "update_time") |
||||
private java.util.Date updateTime; |
||||
@Column(name = "status") |
||||
private String status; |
||||
|
||||
} |
@ -0,0 +1,37 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcTokenDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_token") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcToken extends BaseModel { |
||||
@Id |
||||
@Column(name = "token_id") |
||||
private Integer tokenId; |
||||
@Column(name = "token_symbol") |
||||
private String tokenSymbol; |
||||
@Column(name = "issue_time") |
||||
private java.util.Date issueTime; |
||||
@Column(name = "total_supply") |
||||
private String totalSupply; |
||||
@Column(name = "total_circulation") |
||||
private String totalCirculation; |
||||
@Column(name = "descr") |
||||
private String descr; |
||||
|
||||
} |
@ -0,0 +1,37 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcTransferAuditingDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_transfer_auditing") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcTransferAuditing extends BaseModel { |
||||
@Id |
||||
@Column(name = "id") |
||||
private String id; |
||||
@Column(name = "sys_user_id") |
||||
private String sysUserId; |
||||
@Column(name = "ip_addr") |
||||
private String ipAddr; |
||||
@Column(name = "transfer_id") |
||||
private String transferId; |
||||
@Column(name = "transfer_status") |
||||
private String transferStatus; |
||||
@Column(name = "create_time") |
||||
private java.util.Date createTime; |
||||
|
||||
} |
@ -0,0 +1,43 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcWalletDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_wallet") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWallet extends BaseModel { |
||||
@Column(name = "addr") |
||||
private String addr; |
||||
@Column(name = "token_id") |
||||
private Integer tokenId; |
||||
@Column(name = "user_open_id") |
||||
private String userOpenId; |
||||
@Column(name = "token_symbol") |
||||
private String tokenSymbol; |
||||
@Column(name = "balance") |
||||
private Double balance; |
||||
@Column(name = "free_balance") |
||||
private Double freeBalance; |
||||
@Column(name = "freeze_balance") |
||||
private Double freezeBalance; |
||||
@Column(name = "create_time") |
||||
private java.util.Date createTime; |
||||
@Column(name = "update_time") |
||||
private java.util.Date updateTime; |
||||
@Column(name = "wallet_type") |
||||
private String walletType; |
||||
|
||||
} |
@ -0,0 +1,29 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcWalletKeyDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_wallet_key") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletKey extends BaseModel { |
||||
@Id |
||||
@Column(name = "addr") |
||||
private String addr; |
||||
@Column(name = "private_key") |
||||
private String privateKey; |
||||
|
||||
} |
@ -0,0 +1,39 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcWalletOutDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_wallet_out") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletOut extends BaseModel { |
||||
@Id |
||||
@Column(name = "id") |
||||
private String id; |
||||
@Column(name = "addr") |
||||
private String addr; |
||||
@Column(name = "token_id") |
||||
private Integer tokenId; |
||||
@Column(name = "token_symbol") |
||||
private String tokenSymbol; |
||||
@Column(name = "private_key") |
||||
private String privateKey; |
||||
@Column(name = "password") |
||||
private String password; |
||||
@Column(name = "remark") |
||||
private String remark; |
||||
|
||||
} |
@ -0,0 +1,57 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Id; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* BtcWalletTransferDTO 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:08:16 |
||||
*/ |
||||
@Table(name = "dapp_btc_wallet_transfer") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class BtcWalletTransfer extends BaseModel { |
||||
@Id |
||||
@Column(name = "id") |
||||
private String id; |
||||
@Column(name = "hash") |
||||
private String hash; |
||||
@Column(name = "from_addr") |
||||
private String fromAddr; |
||||
@Column(name = "to_addr") |
||||
private String toAddr; |
||||
@Column(name = "amount") |
||||
private Double amount; |
||||
@Column(name = "token_id") |
||||
private Integer tokenId; |
||||
@Column(name = "token_symbol") |
||||
private String tokenSymbol; |
||||
@Column(name = "gas_price") |
||||
private Double gasPrice; |
||||
@Column(name = "gas_token_type") |
||||
private String gasTokenType; |
||||
@Column(name = "gas_token_name") |
||||
private String gasTokenName; |
||||
@Column(name = "gas_token_symbol") |
||||
private String gasTokenSymbol; |
||||
@Column(name = "transfer_type") |
||||
private String transferType; |
||||
@Column(name = "status") |
||||
private Integer status; |
||||
@Column(name = "remark") |
||||
private String remark; |
||||
@Column(name = "create_time") |
||||
private java.util.Date createTime; |
||||
@Column(name = "update_time") |
||||
private java.util.Date updateTime; |
||||
|
||||
} |
@ -0,0 +1,34 @@ |
||||
package com.blockchain.server.btc.entity; |
||||
|
||||
import com.blockchain.common.base.entity.BaseModel; |
||||
import lombok.AllArgsConstructor; |
||||
import lombok.Data; |
||||
import lombok.NoArgsConstructor; |
||||
|
||||
import javax.persistence.Column; |
||||
import javax.persistence.Table; |
||||
|
||||
/** |
||||
* EthApplication 数据传输类 |
||||
* |
||||
* @version 1.0 |
||||
* @date 2019-02-16 15:44:06 |
||||
*/ |
||||
@Table(name = "config_wallet_param") |
||||
@Data |
||||
@AllArgsConstructor |
||||
@NoArgsConstructor |
||||
public class ConfigWalletParam extends BaseModel { |
||||
@Column(name = "id") |
||||
private String id; |
||||
@Column(name = "module_type") |
||||
private String moduleType; |
||||
@Column(name = "param_name") |
||||
private String paramName; |
||||
@Column(name = "param_value") |
||||
private String paramValue; |
||||
@Column(name = "param_descr") |
||||
private String paramDescr; |
||||
@Column(name = "status") |
||||
private Integer status; |
||||
} |
@ -0,0 +1,31 @@ |
||||
package com.blockchain.server.btc.feign; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
||||
@FeignClient("dapp-ore-server") |
||||
public interface CoinFegin { |
||||
|
||||
|
||||
/** |
||||
* 挖矿激活 |
||||
* |
||||
* @param inviteUserIdHex 邀请码 |
||||
* @return |
||||
*/ |
||||
@PostMapping("/orePower/insertPower") |
||||
ResultDTO<Integer> insertPower(@RequestParam("inviteUserIdHex") String inviteUserIdHex); |
||||
|
||||
/** |
||||
* 提取矿金交易状态回调 |
||||
* |
||||
* @param hash 交易hash |
||||
* @param status 交易状态 |
||||
* @return |
||||
*/ |
||||
@PostMapping("/oreDigedCoin/extractCoinCallBack") |
||||
ResultDTO<String> extractCoinCallBack(@RequestParam("hash") String hash, @RequestParam("status") Boolean status); |
||||
|
||||
} |
@ -0,0 +1,20 @@ |
||||
package com.blockchain.server.btc.feign; |
||||
|
||||
import com.blockchain.common.base.dto.ResultDTO; |
||||
import org.springframework.cloud.openfeign.FeignClient; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.RequestParam; |
||||
|
||||
@FeignClient("dapp-eth-server") |
||||
public interface EthServerFegin { |
||||
|
||||
/** |
||||
* 验证钱包密码 调用eth |
||||
* |
||||
* @param password 加密密码 |
||||
* @return |
||||
*/ |
||||
@GetMapping("inner/wallet/isPassword") |
||||
ResultDTO isPassword(@RequestParam(name = "password", required = false) String password); |
||||
|
||||
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue