pull/1/head
liushaodong 5 years ago
commit 4d5a5032e1
  1. 30
      .gitignore
  2. 21
      blockchain-common/blockchain-common-base/pom.xml
  3. 18
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/constant/BaseConstant.java
  4. 11
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/constant/PushConstants.java
  5. 24
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/constant/TokenTypeEnums.java
  6. 6
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/BaseDTO.java
  7. 17
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/GasDTO.java
  8. 22
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/MarketDTO.java
  9. 54
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/PageDTO.java
  10. 49
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/ResultDTO.java
  11. 15
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/SessionUserDTO.java
  12. 18
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/TokenDTO.java
  13. 19
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/WalletChangeDTO.java
  14. 18
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/dto/WalletOrderDTO.java
  15. 10
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/entity/BaseModel.java
  16. 57
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/enums/BaseResultEnums.java
  17. 94
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/enums/PushEnums.java
  18. 57
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/exception/BaseException.java
  19. 17
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/exception/RPCException.java
  20. 757
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/DateTimeUtils.java
  21. 79
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/ExceptionPreconditionUtils.java
  22. 138
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/FileUploadHelper.java
  23. 74
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/HttpRequestUtil.java
  24. 160
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/HttpUtilManager.java
  25. 273
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/JsonUtils.java
  26. 38
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/MD5Utils.java
  27. 265
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/RSACoderUtils.java
  28. 162
      blockchain-common/blockchain-common-base/src/main/java/com/blockchain/common/base/util/SSOHelper.java
  29. 230
      blockchain-common/blockchain-common-pom/pom.xml
  30. 45
      blockchain-common/blockchain-common-tx/pom.xml
  31. 8
      blockchain-common/blockchain-common-tx/src/main/resources/README.md
  32. 22
      blockchain-common/pom.xml
  33. 15
      blockchain-server/blockchain-server-base/pom.xml
  34. 8
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/BaseConf.java
  35. 13
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/annotation/BypassedFeign.java
  36. 68
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/aop/FeignAop.java
  37. 66
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/aop/MethodAop.java
  38. 26
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/DateConvertConfig.java
  39. 32
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/FeginConf.java
  40. 73
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/GlobalExceptionHandle.java
  41. 27
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/InnerInterceptorConf.java
  42. 91
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/RedisConf.java
  43. 24
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/RestTemplateConf.java
  44. 19
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/SpringCloudConf.java
  45. 40
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/SwaggerConf.java
  46. 17
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/TkMybatisConf.java
  47. 45
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/conf/XssFilterConfig.java
  48. 28
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/controller/BaseController.java
  49. 92
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/filter/XssFilter.java
  50. 40
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/filter/XssHttpServletRequestWrapper.java
  51. 34
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/interceptor/InnerInterceptor.java
  52. 20
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/interceptor/LoginInterceptor.java
  53. 46
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/interceptor/StringToDateConverter.java
  54. 28
      blockchain-server/blockchain-server-base/src/main/java/com/blockchain/server/base/redis/IpInnerCache.java
  55. 35
      blockchain-server/blockchain-server-base/src/main/resources/README.md
  56. 5
      blockchain-server/blockchain-server-base/src/main/resources/i18n/MessgesBundle_default.properties
  57. 35
      blockchain-server/blockchain-server-btc/pom.xml
  58. 49
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/BtcApplication.java
  59. 32
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/config/InterceptorConf.java
  60. 14
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/BtcAddressConstans.java
  61. 13
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/BtcApplicationConstans.java
  62. 20
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/BtcBlockNumberConstans.java
  63. 15
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/BtcConfigConstants.java
  64. 12
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/BtcConstans.java
  65. 38
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/BtcTransferConstans.java
  66. 27
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/constants/UsdtConstans.java
  67. 73
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/enums/BtcEnums.java
  68. 40
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/exception/BtcException.java
  69. 53
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/util/BtcAddressSetRedisUtils.java
  70. 43
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/util/BtcBlockRedisUtils.java
  71. 60
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/util/BtcRASUtils.java
  72. 22
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/common/util/CheckEthFeginResult.java
  73. 35
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/BtcTokenController.java
  74. 54
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/BtcWalletController.java
  75. 72
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/BtcWalletTransferController.java
  76. 29
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/ConfigWalletParamController.java
  77. 17
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/api/BtcTokenApi.java
  78. 29
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/api/BtcWalletApi.java
  79. 33
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/api/BtcWalletTransferApi.java
  80. 12
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/controller/api/ConfigWalletParamApi.java
  81. 21
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcApplicationDTO.java
  82. 23
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcBlockNumberDTO.java
  83. 25
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcTokenDTO.java
  84. 25
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcTransferAuditingDTO.java
  85. 29
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcWalletDTO.java
  86. 21
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcWalletKeyDTO.java
  87. 26
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcWalletOutDTO.java
  88. 35
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/BtcWalletTransferDTO.java
  89. 24
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/dto/ConfigWalletParamDTO.java
  90. 29
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcApplication.java
  91. 33
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcBlockNumber.java
  92. 37
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcToken.java
  93. 37
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcTransferAuditing.java
  94. 43
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcWallet.java
  95. 29
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcWalletKey.java
  96. 39
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcWalletOut.java
  97. 57
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/BtcWalletTransfer.java
  98. 34
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/entity/ConfigWalletParam.java
  99. 31
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/feign/CoinFegin.java
  100. 20
      blockchain-server/blockchain-server-btc/src/main/java/com/blockchain/server/btc/feign/EthServerFegin.java
  101. Some files were not shown because too many files have changed in this diff Show More

30
.gitignore vendored

@ -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…
Cancel
Save