src/main/java/com/xcong/excoin/common/contants/WalletConstants.java
New file @@ -0,0 +1,16 @@ package com.xcong.excoin.common.contants; public class WalletConstants { public static final String ADDRESS_PREFIX = "ROC"; /** * 是否是主币 */ public static final Integer IS_MAIN = 1; /** * 是否是本位币 */ public static final Integer IS_MAIN_BASIC = -1; } src/main/java/com/xcong/excoin/common/system/controller/LoginController.java
@@ -15,13 +15,19 @@ import com.xcong.excoin.common.response.Result; import com.xcong.excoin.common.system.bean.LoginUserBean; import com.xcong.excoin.common.system.dto.LoginDto; import com.xcong.excoin.common.system.dto.OutCenterRegisterDto; import com.xcong.excoin.common.system.dto.RegisterDto; import com.xcong.excoin.common.system.entity.WtWallet; import com.xcong.excoin.common.system.vo.LoginVo; import com.xcong.excoin.configurations.properties.ApplicationProperties; import com.xcong.excoin.configurations.properties.SecurityProperties; import com.xcong.excoin.modules.member.service.MemberService; import com.xcong.excoin.utils.RedisUtils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiResponse; import io.swagger.annotations.ApiResponses; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -117,5 +123,23 @@ public Result register(@RequestBody @Validated RegisterDto registerDto) { return memberservice.register(registerDto); } @ApiOperation(value = "创建接口", notes = "创建接口") @PostMapping(value = "/registerOutCenter") @ApiResponses({ @ApiResponse(code = 200,message = "OK",response = LoginVo.class), }) public Result registerOutCenter(@RequestBody @Validated OutCenterRegisterDto outCenterRegisterDto) { return memberservice.registerOutCenter(outCenterRegisterDto); } @ApiOperation(value = "导入接口", notes = "导入接口") @PostMapping(value = "/loginOutCenter") @ApiResponses({ @ApiResponse(code = 200,message = "OK",response = LoginVo.class), }) public Result recovery(@RequestBody WtWallet wallet) { return memberservice.recovery(wallet); } } src/main/java/com/xcong/excoin/common/system/dao/WalletDetailDao.java
New file @@ -0,0 +1,36 @@ package com.xcong.excoin.common.system.dao; import java.math.BigDecimal; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import com.xcong.excoin.common.system.entity.WtWalletDetail; /** * @description 钱包表 * @author admin * @date 2020-09-17 14:31 */ @Mapper public interface WalletDetailDao { int insert(@Param("item") WtWalletDetail wtWalletDetail); int batchInsert(@Param("list") List<WtWalletDetail> wtWalletDetailList); int updateByModel(@Param("record") WtWalletDetail wtWalletDetail); int deleteByIds(@Param("list") List<String> list); int deleteById(String id); List<WtWalletDetail> selectByModel( WtWalletDetail wtWalletDetail); WtWalletDetail selectById(String id); WtWalletDetail selectByAddressAndSymbol(@Param("address")String address,@Param("symbol")String symbol); void updateWalletBalance(@Param("id") Long id, @Param("balance") BigDecimal balance); } src/main/java/com/xcong/excoin/common/system/dao/WtTokenDao.java
New file @@ -0,0 +1,28 @@ package com.xcong.excoin.common.system.dao; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import com.xcong.excoin.common.system.entity.WtToken; @Mapper public interface WtTokenDao { int insert(@Param("item") WtToken wtToken); int batchInsert(@Param("list") List<WtToken> wtTokenList); int updateByModel(@Param("record") WtToken wtToken); int deleteById(Integer id); WtToken selectById(Integer id); WtToken selectBySymbol(String symbol); List<WtToken> selectAllToken(); WtToken selectMainToken(); } src/main/java/com/xcong/excoin/common/system/dao/WtWalletDao.java
New file @@ -0,0 +1,39 @@ package com.xcong.excoin.common.system.dao; import java.util.List; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import com.xcong.excoin.common.system.entity.WtWallet; @Mapper public interface WtWalletDao { int insert(@Param("item") WtWallet wtWallet); int batchInsert(@Param("list") List<WtWallet> wtWalletList); int updateByModel(@Param("record") WtWallet wtWallet); int deleteByIds(@Param("list") List<String> list); int deleteById(String address); int clearTerminalId(String address); int deleteTerminal(String terminalId); WtWallet selectById(String address); /** * 只有name信息 * @param address * @return */ WtWallet selectSimpleById(String address); WtWallet selectSimpleByTerminalId(String terminalId); WtWallet selectByMnemonicWords(String mnemonicWords); } src/main/java/com/xcong/excoin/common/system/dao/WtWordDao.java
New file @@ -0,0 +1,10 @@ package com.xcong.excoin.common.system.dao; import java.util.List; import org.apache.ibatis.annotations.Mapper; @Mapper public interface WtWordDao { List<String> selectAllWords(); } src/main/java/com/xcong/excoin/common/system/dto/OutCenterRegisterDto.java
New file @@ -0,0 +1,20 @@ package com.xcong.excoin.common.system.dto; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "OutCenterRegisterDto", description = "注册接口参数类") public class OutCenterRegisterDto { @ApiModelProperty(value = "推荐人Uid", example = "rxadr3") private String refererId; @ApiModelProperty(value = "资金交易密码", example = "1qazwsx") private String password; @ApiModelProperty(value = "钱包名称", example = "qwer") private String walletName; @ApiModelProperty(value = "终端ID", example = "21220sdsf") private String terminalId; } src/main/java/com/xcong/excoin/common/system/entity/WtBlock.java
New file @@ -0,0 +1,68 @@ package com.xcong.excoin.common.system.entity; import java.math.BigDecimal; import java.util.Date; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * @description 区块信息表 * @author admin * @date 2020-09-17 14:31 */ @Data @TableName("wt_block") public class WtBlock { /** * 主键 */ private String id; /** * 区块高度 */ private Long block; /** * 累计交易 */ private Long totalTransaction; /** * 更新时间 */ private Date updateTime; /** * 流通总量 */ private BigDecimal totalAmount; /** * 持币地址数 */ private Integer holdCount; /** * 平均出块速度 */ private Integer blockAvg; /** * 超级节点 */ private Integer superNode; } src/main/java/com/xcong/excoin/common/system/entity/WtToken.java
New file @@ -0,0 +1,57 @@ package com.xcong.excoin.common.system.entity; import java.math.BigDecimal; import java.util.Date; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; /** * @description 代币表 * @author admin * @date 2020-09-17 14:31 */ @Data @TableName("wt_token") public class WtToken { /** * 主键 */ private Integer id; /** * 币种:NEK,MUSD */ private String symbol; /** * USDT汇率 */ private BigDecimal price; /** * 是否主币(0:否 1:是) */ private Integer main; /** * 手续费(按主币收取) */ private BigDecimal fee; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date createTime; private BigDecimal amount; private String contractAddress; private String symbolName; } src/main/java/com/xcong/excoin/common/system/entity/WtWallet.java
New file @@ -0,0 +1,51 @@ package com.xcong.excoin.common.system.entity; import java.util.List; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @Data @TableName("wt_wallet") public class WtWallet { /** * 主键 */ private String address; /** * 私钥 */ private String privateKey; /** * 助记词 12个单词逗号隔开 */ private String mnemonicWords; /** * 密码:通过助记词导入后重置 */ private String password; /** * 钱包名称 */ private String walletName; /** * 终端ID */ private String terminalId; @TableField(exist = false) private List<String> mnemonicWordList; } src/main/java/com/xcong/excoin/common/system/entity/WtWalletDetail.java
New file @@ -0,0 +1,53 @@ package com.xcong.excoin.common.system.entity; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * @description 钱包表 * @author admin * @date 2020-09-17 14:31 */ @Data @TableName("wt_wallet_detail") public class WtWalletDetail { /** * 主键 */ private Long id; /** * 主地址 */ private String address; /** * 币种 */ private String symbol; /** * 余额 */ private BigDecimal balance; /** * 主钱包 0:否 1:是 */ private Integer main; /** * 是否显示 0显示 1不显示 */ private Integer isShow; } src/main/java/com/xcong/excoin/common/system/vo/LoginVo.java
New file @@ -0,0 +1,26 @@ package com.xcong.excoin.common.system.vo; import java.util.List; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data @ApiModel(value = "LoginVo", description = "注册返回") public class LoginVo { @ApiModelProperty(value = "助记词") private List<String> mnemonicWordList; @ApiModelProperty(value = "地址") /** * 主键 */ private String address; @ApiModelProperty(value = "地址MD5") private String addressMd; } src/main/java/com/xcong/excoin/configurations/security/TokenFilter.java
@@ -55,9 +55,9 @@ String redisKey = ""; // 根据user-agent判断pc端还是app端 if (LoginUserUtils.isBrowser(request)) { redisKey = AppContants.PC_LOGIN_PREFIX + token; redisKey = token; } else { redisKey = AppContants.APP_LOGIN_PREFIX + token; redisKey = token; } String loginStr = (String) redisUtils.get(redisKey); @@ -65,7 +65,6 @@ MemberEntity loginUser = JSONObject.parseObject(loginStr, MemberEntity.class); Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser, token, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authentication); redisUtils.expire(redisKey, 36000); } else { log.info("token无法查询:{}", token); SecurityContextHolder.clearContext(); @@ -80,6 +79,40 @@ } filterChain.doFilter(servletRequest, servletResponse); } /** * 解析前端传来的token,md5加密后的地址_/api_设备iD * * @param request * @return */ private String resolveTokenOutCenter(HttpServletRequest request) { try { String bearerToken = request.getHeader(AppContants.TOKEN_HEADER); //获取请求的完整路径 StringBuffer requestURL = request.getRequestURL(); if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(AppContants.TOKEN_START_WITH)) { // 去掉令牌前缀 String rsaToken = bearerToken.replace(AppContants.TOKEN_START_WITH, ""); RSA rsa = new RSA(securityProperties.getPrivateKey(), null); String[] tokens = StrUtil.split(rsa.decryptStr(rsaToken, KeyType.PrivateKey), "_"); if (StrUtil.isNotEmpty(requestURL) && requestURL.toString().contains(tokens[1])) { return tokens[0]; } else { // log.info("前面token为{}", tokens[0]); // log.info("时间为:{}, 当前时间为:{}", tokens[1], System.currentTimeMillis()); return AppContants.TIME_OUT; } } // log.info("bearerToken---->{}", bearerToken); } catch (Exception e) { log.error("#解析token异常#", e); return null; } return null; } /** * 解析前端传来的token,先去掉Bearer,在rsa解密得到token_time,返回token,并判断time与当前是否在5s内 src/main/java/com/xcong/excoin/modules/member/entity/MemberEntity.java
@@ -94,6 +94,10 @@ * 交易密码 */ private String tradePassword; /** * 钱包地址 */ private String address; /** * 交易密码时效性设置 src/main/java/com/xcong/excoin/modules/member/service/MemberService.java
@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.common.system.dto.OutCenterRegisterDto; import com.xcong.excoin.common.system.dto.RegisterDto; import com.xcong.excoin.common.system.entity.WtWallet; import com.xcong.excoin.modules.member.entity.MemberEntity; import com.xcong.excoin.modules.member.parameter.dto.MemberAddCoinAddressDto; import com.xcong.excoin.modules.member.parameter.dto.MemberAuthenticationDto; @@ -90,5 +92,10 @@ public Result getPcVersionInfo(); public Result registerOutCenter(OutCenterRegisterDto outCenterRegisterDto); public Result recovery(WtWallet wallet); } src/main/java/com/xcong/excoin/modules/member/service/impl/MemberServiceImpl.java
@@ -5,14 +5,27 @@ import cn.hutool.core.util.StrUtil; import cn.hutool.crypto.SecureUtil; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.xcong.excoin.common.LoginUserUtils; import com.xcong.excoin.common.contants.AppContants; import com.xcong.excoin.common.contants.WalletConstants; import com.xcong.excoin.common.enumerates.CoinTypeEnum; import com.xcong.excoin.common.enumerates.SymbolEnum; import com.xcong.excoin.common.response.Result; import com.xcong.excoin.common.system.dao.WalletDetailDao; import com.xcong.excoin.common.system.dao.WtTokenDao; import com.xcong.excoin.common.system.dao.WtWalletDao; import com.xcong.excoin.common.system.dao.WtWordDao; import com.xcong.excoin.common.system.dto.OutCenterRegisterDto; import com.xcong.excoin.common.system.dto.RegisterDto; import com.xcong.excoin.common.system.entity.WtToken; import com.xcong.excoin.common.system.entity.WtWallet; import com.xcong.excoin.common.system.entity.WtWalletDetail; import com.xcong.excoin.common.system.service.CommonService; import com.xcong.excoin.common.system.vo.LoginVo; import com.xcong.excoin.modules.coin.dao.MemberAccountMoneyChangeDao; import com.xcong.excoin.modules.coin.entity.MemberAccountMoneyChange; import com.xcong.excoin.modules.member.dao.*; @@ -35,12 +48,18 @@ import com.xcong.excoin.modules.platform.dao.PlatformSymbolsCoinDao; import com.xcong.excoin.modules.platform.entity.PlatformFeeSettingEntity; import com.xcong.excoin.modules.platform.entity.PlatformSymbolsCoinEntity; import com.xcong.excoin.utils.MD5Util; import com.xcong.excoin.utils.MessageSourceUtils; import com.xcong.excoin.utils.RedisUtils; import com.xcong.excoin.utils.ShareCodeUtil; import com.xcong.excoin.utils.ThreadPoolUtils; import com.xcong.excoin.utils.ToolUtil; import com.xcong.excoin.utils.UUIDUtil; import com.xcong.excoin.utils.WordsUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; @@ -51,6 +70,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; import javax.annotation.Resource; import javax.validation.Valid; @@ -112,7 +132,18 @@ @Resource private MemberWalletContractSimulateDao memberWalletContractSimulateDao; @Resource private WtWalletDao wtWalletDao; @Resource private WtWordDao wtWordDao; @Resource private WtTokenDao wtTokenDao; @Resource private WalletDetailDao walletDetailDao; @Transactional() @Override public Result register(RegisterDto registerDto) { @@ -1020,6 +1051,330 @@ } return Result.ok(arrayList); } @Transactional() @Override public Result registerOutCenter(OutCenterRegisterDto outCenterRegisterDto) { LoginVo loginVo = new LoginVo(); log.info("钱包初始化"); /** * 钱包初始化 */ // 创建钱包需要先清除这个设备之前的钱包 //wtWalletDao.deleteTerminal(outCenterRegisterDto.getTerminalId()); WtWallet wtWallet = new WtWallet(); wtWallet.setWalletName(outCenterRegisterDto.getWalletName()); wtWallet.setTerminalId(outCenterRegisterDto.getTerminalId()); wtWallet.setPassword(MD5Util.strToMD5(outCenterRegisterDto.getPassword())); // 校验钱包名和密码 // 得到助记词 List<String> words = getWords(); wtWallet.setMnemonicWordList(words); loginVo.setMnemonicWordList(words); if(CollectionUtils.isEmpty(words)){ // 报错 不能生成钱包 return Result.fail(MessageSourceUtils.getString("login_init")); } // 创建钱包 // 生成钱包地址和私钥 34 52 42 64 // 公链钱包地址36位 私钥 46 String randomID = UUIDUtil.getRandomID(); String address = WalletConstants.ADDRESS_PREFIX+randomID; String privateKey = (UUIDUtil.getRandomID()+UUIDUtil.getRandomID()).substring(0,46); wtWallet.setAddress(address); loginVo.setAddress(address); String strToMD5 = MD5Util.strToMD5(address); loginVo.setAddressMd(strToMD5); wtWallet.setPrivateKey(privateKey); wtWallet.setMnemonicWords(ToolUtil.listToString(words,",")); wtWalletDao.insert(wtWallet); // 同时需要创建各个token List<WtToken> wtTokens = wtTokenDao.selectAllToken(); List<WtWalletDetail> wtWalletDetails = new ArrayList<>(); WtWalletDetail wtWalletDetail = null; if(CollectionUtils.isNotEmpty(wtTokens)){ for(WtToken token : wtTokens){ wtWalletDetail = new WtWalletDetail(); String symbol = token.getSymbol(); wtWalletDetail.setAddress(address); wtWalletDetail.setBalance(BigDecimal.ZERO); wtWalletDetail.setSymbol(symbol); wtWalletDetail.setMain(token.getMain()); wtWalletDetail.setIsShow(0); wtWalletDetails.add(wtWalletDetail); } walletDetailDao.batchInsert(wtWalletDetails); } // 置空敏感信息 wtWallet.setTerminalId(null); wtWallet.setPassword(null); wtWallet.setPrivateKey(null); // 查询是否存在该账号用户 // MemberEntity member = memberDao.selectMemberInfoByAccount(registerDto.getAccount()); // if (member != null) { // return Result.fail("账号已存在"); // } // boolean isTrue = commonservice.verifyCode(registerDto.getAccount(), registerDto.getCode()); // if (!isTrue) { // return Result.fail(MessageSourceUtils.getString("common_verify_code")); // } log.info("用户初始化"); /** * 用户初始化 */ MemberEntity member = new MemberEntity(); member.setAddress(address); member.setPassword(SecureUtil.md5(outCenterRegisterDto.getPassword())); member.setTradePassword(SecureUtil.md5(outCenterRegisterDto.getPassword())); // 判断账号类型 // if (MemberEntity.ACCOUNT_TYPE_PHONE.equals(registerDto.getType())) { // member.setPhone(registerDto.getAccount()); // } else if (MemberEntity.ACCOUNT_TYPE_EMAIL.equals(registerDto.getType())) { // member.setEmail(registerDto.getAccount()); // } else { // return Result.fail("账号类型错误"); // } // 判断是否拥有推荐人,若为空则默认系统 // if (StrUtil.isBlank(registerDto.getRefererId())) { // registerDto.setRefererId(AppContants.SYSTEM_REFERER); // } // if (!AppContants.SYSTEM_REFERER.equals(outCenterRegisterDto.getRefererId())) { // MemberEntity isExist = memberDao.selectMemberInfoByInviteId(outCenterRegisterDto.getRefererId()); // if (isExist != null) { // member.setRefererId(outCenterRegisterDto.getRefererId()); // } // } member.setAccountStatus(MemberEntity.ACCOUNT_STATUS_ENABLE); member.setAccountType(MemberEntity.ACCOUNT_TYPE_NORMAL); member.setAgentLevel(MemberEntity.ACCOUNT_AGENT_LEVEL); member.setCertifyStatus(MemberEntity.CERTIFY_STATUS_UN_SUBMIT); member.setIsForce(1); member.setIsProfit(0); memberDao.insert(member); MemberSettingEntity memberSettingEntity = new MemberSettingEntity(); memberSettingEntity.setSpread(BigDecimal.ONE); memberSettingEntity.setClosingSpread(BigDecimal.valueOf(5)); memberSettingEntity.setForceParam(BigDecimal.valueOf(0.0030)); memberSettingEntity.setMemberId(member.getId()); memberSettingDao.insert(memberSettingEntity); String inviteId = ShareCodeUtil.toSerialCode(member.getId()); member.setInviteId(inviteId); // boolean flag = false; // String parentId = member.getRefererId(); // String ids = ""; // while (!flag && StringUtils.isNotBlank(parentId)) { // ids += ("," + parentId); // MemberEntity parentMember = memberDao.selectMemberInfoByInviteId(parentId); // if (parentMember == null) { // break; // } // parentId = parentMember.getRefererId(); // if(StringUtils.isBlank(parentId)){ // break; // } // if (parentMember.getRefererId().equals(parentMember.getInviteId())) { // flag = true; // } // } // member.setRefererIds(ids); memberDao.updateById(member); //初始化合约钱包 MemberWalletContractEntity walletContract = new MemberWalletContractEntity(); walletContract.setMemberId(member.getId()); walletContract.setAvailableBalance(AppContants.INIT_MONEY); walletContract.setFrozenBalance(AppContants.INIT_MONEY); walletContract.setTotalBalance(AppContants.INIT_MONEY); walletContract.setBorrowedFund(AppContants.INIT_MONEY); walletContract.setWalletCode(CoinTypeEnum.USDT.name()); memberWalletContractDao.insert(walletContract); MemberWalletContractSimulateEntity walletContractSimulate = new MemberWalletContractSimulateEntity(); walletContractSimulate.setMemberId(member.getId()); walletContractSimulate.setAvailableBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY)); walletContractSimulate.setTotalBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY)); walletContractSimulate.setFrozenBalance(AppContants.INIT_MONEY); walletContractSimulate.setBorrowedFund(AppContants.INIT_MONEY); walletContractSimulate.setWalletCode(CoinTypeEnum.USDT.name()); memberWalletContractSimulateDao.insert(walletContractSimulate); // 初始化币币钱包 for (CoinTypeEnum coinTypeEnum : CoinTypeEnum.values()) { MemberWalletCoinEntity walletCoin = new MemberWalletCoinEntity(); walletCoin.setWalletCode(coinTypeEnum.name()); walletCoin.setMemberId(member.getId()); walletCoin.setAvailableBalance(AppContants.INIT_MONEY); walletCoin.setFrozenBalance(AppContants.INIT_MONEY); walletCoin.setTotalBalance(AppContants.INIT_MONEY); walletCoin.setBorrowedFund(AppContants.INIT_MONEY); memberWalletCoinDao.insert(walletCoin); } // 初始化代理佣金钱包 MemberWalletAgentEntity walletAgent = new MemberWalletAgentEntity(); walletAgent.setMemberId(member.getId()); walletAgent.setWalletCode(CoinTypeEnum.USDT.name()); memberWalletAgentDao.insert(walletAgent); // 初始化杠杆 for (SymbolEnum symbolEnum : SymbolEnum.values()) { MemberLevelRateEntity levelRate = new MemberLevelRateEntity(); levelRate.setMemberId(member.getId()); levelRate.setSymbol(symbolEnum.getValue()); memberLevelRateDao.insert(levelRate); } //加密地址为key,member为value redisUtils.set(strToMD5, JSONObject.toJSONString(member)); return Result.ok(loginVo); } public List<String> getWords(){ if(CollectionUtils.isEmpty(WordsUtil.words_list)){ WordsUtil.words_list = wtWordDao.selectAllWords(); } // 随机得12个单词 if(CollectionUtils.isEmpty(WordsUtil.words_list)){ throw new RuntimeException("error"); } int size = WordsUtil.words_list.size(); Random random = new Random(); // 获得12个单词 List<String> zjc = new ArrayList<>(12); boolean loop = true; while (loop){ int randInt = random.nextInt(size - 1); // 根据得到的随机数去取 String s = WordsUtil.words_list.get(randInt); if(!zjc.contains(s)){ zjc.add(s); } if(zjc.size()>=12){ loop = false; } } return zjc; } @Transactional @Override public Result recovery(WtWallet wallet) { LoginVo loginVo = new LoginVo(); /** * 判断钱包是否存在 */ List<String> mnemonicWordList = wallet.getMnemonicWordList(); if(CollectionUtils.isEmpty(mnemonicWordList)){ return Result.fail(MessageSourceUtils.getString("login_recovery_001")); } String mnemonicWords = ToolUtil.listToString(mnemonicWordList, ","); WtWallet wtWallet = wtWalletDao.selectByMnemonicWords(mnemonicWords); if(wtWallet==null){ return Result.fail(MessageSourceUtils.getString("login_recovery_002")); } /** * 通过地址获取该用户是否存在 */ String address = wtWallet.getAddress(); String strToMD5 = MD5Util.strToMD5(address); loginVo.setAddress(address); loginVo.setAddressMd(strToMD5); Wrapper<MemberEntity> queryWrapperOrepool = new QueryWrapper<>(); ((QueryWrapper<MemberEntity>) queryWrapperOrepool).eq("address", address); MemberEntity memberEntity = memberDao.selectOne(queryWrapperOrepool); if(ObjectUtil.isEmpty(memberEntity)) { log.info("用户初始化"); /** * 用户初始化 */ MemberEntity member = new MemberEntity(); member.setAddress(address); member.setPassword(MD5Util.strToMD5(wallet.getPassword())); member.setTradePassword(MD5Util.strToMD5(wallet.getPassword())); member.setAccountStatus(MemberEntity.ACCOUNT_STATUS_ENABLE); member.setAccountType(MemberEntity.ACCOUNT_TYPE_NORMAL); member.setAgentLevel(MemberEntity.ACCOUNT_AGENT_LEVEL); member.setCertifyStatus(MemberEntity.CERTIFY_STATUS_UN_SUBMIT); member.setIsForce(1); member.setIsProfit(0); memberDao.insert(member); MemberSettingEntity memberSettingEntity = new MemberSettingEntity(); memberSettingEntity.setSpread(BigDecimal.ONE); memberSettingEntity.setClosingSpread(BigDecimal.valueOf(5)); memberSettingEntity.setForceParam(BigDecimal.valueOf(0.0030)); memberSettingEntity.setMemberId(member.getId()); memberSettingDao.insert(memberSettingEntity); String inviteId = ShareCodeUtil.toSerialCode(member.getId()); member.setInviteId(inviteId); memberDao.updateById(member); //初始化合约钱包 MemberWalletContractEntity walletContract = new MemberWalletContractEntity(); walletContract.setMemberId(member.getId()); walletContract.setAvailableBalance(AppContants.INIT_MONEY); walletContract.setFrozenBalance(AppContants.INIT_MONEY); walletContract.setTotalBalance(AppContants.INIT_MONEY); walletContract.setBorrowedFund(AppContants.INIT_MONEY); walletContract.setWalletCode(CoinTypeEnum.USDT.name()); memberWalletContractDao.insert(walletContract); MemberWalletContractSimulateEntity walletContractSimulate = new MemberWalletContractSimulateEntity(); walletContractSimulate.setMemberId(member.getId()); walletContractSimulate.setAvailableBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY)); walletContractSimulate.setTotalBalance(new BigDecimal(AppContants.INIT_SIMULATE_MONEY)); walletContractSimulate.setFrozenBalance(AppContants.INIT_MONEY); walletContractSimulate.setBorrowedFund(AppContants.INIT_MONEY); walletContractSimulate.setWalletCode(CoinTypeEnum.USDT.name()); memberWalletContractSimulateDao.insert(walletContractSimulate); // 初始化币币钱包 for (CoinTypeEnum coinTypeEnum : CoinTypeEnum.values()) { MemberWalletCoinEntity walletCoin = new MemberWalletCoinEntity(); walletCoin.setWalletCode(coinTypeEnum.name()); walletCoin.setMemberId(member.getId()); walletCoin.setAvailableBalance(AppContants.INIT_MONEY); walletCoin.setFrozenBalance(AppContants.INIT_MONEY); walletCoin.setTotalBalance(AppContants.INIT_MONEY); walletCoin.setBorrowedFund(AppContants.INIT_MONEY); memberWalletCoinDao.insert(walletCoin); } // 初始化代理佣金钱包 MemberWalletAgentEntity walletAgent = new MemberWalletAgentEntity(); walletAgent.setMemberId(member.getId()); walletAgent.setWalletCode(CoinTypeEnum.USDT.name()); memberWalletAgentDao.insert(walletAgent); // 初始化杠杆 for (SymbolEnum symbolEnum : SymbolEnum.values()) { MemberLevelRateEntity levelRate = new MemberLevelRateEntity(); levelRate.setMemberId(member.getId()); levelRate.setSymbol(symbolEnum.getValue()); memberLevelRateDao.insert(levelRate); } //加密地址为key,member为value redisUtils.set(strToMD5, JSONObject.toJSONString(member)); }else { redisUtils.set(strToMD5, JSONObject.toJSONString(memberEntity)); } return Result.ok(loginVo); } } src/main/java/com/xcong/excoin/utils/AddressRsaUtil.java
New file @@ -0,0 +1,19 @@ package com.xcong.excoin.utils; public class AddressRsaUtil { public final static String private_key = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJPg33yoN16c8Lfl7KpQ8N87R6c3HLpOZ/4Se1+xTNK3c+a6RL3VzpVqKF0zFax6O+MDzOK+PiYPD3K4+KjleSKckO3cm5kDRmjgEkpiEeMwYVrpdixyXCzlkt1bLVauj89GNLWwaydiqVypkXoLnqpcmomnjPFbq7e28AEWBHdTAgMBAAECgYBDlFrN3xoetN4VTJARbZgGjFK8iiUoxzgjFlMnciFHkur2oF1V2+XixnbX0Maw4dOIdW4mmQZR4kQPC5Unqmbmxf+TOcoHY42o3T4a2DIeG6LSlB3/AZ+z+Ht3xs8TcSkHeWzk5GRfgDFkLIeZmT9FCjctLDZmXd4/eitals03YQJBANJ6ZuSSP2iY4WDlC+4PlQysMRFsDw+y2PMV6du9ssTjtk+LOxD/xiHU5n6pnr40ylzbpEuNi8EBphlObS+glrsCQQCz3H7sKWkUMshQXKXpFeTIvIM1mK3GPBODlForQJM+NCtnwqyu9xl7oTCoy97rWSuqpOZA58z1jdVM6vX02rRJAkEAjpq16fmYkpK6aP7m9VWDZAGqgSZYkgdX7GMVfndpjvLFi+FGlL7nC/cGcB0WW8LCtOVvzGzLmmo2koDLg3BnjwJARc6ihE5eNjSvgmEzE5Anx7FCy56Cc5oFiOAfTwI1I8NjxVXNZ+sHvPAGzryxvG5TgFuX8kEFT5jI3J2k8G+h4QJBALkpNsc0jj7lrFY6vVd9ZNjHPB5Yo0PgZI+WGXNMzm+EmTLc9cOsE82rQQ2K4u4vMGYZ3PyKaBrw7xBj5PsKEcI="; public final static String public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCT4N98qDdenPC35eyqUPDfO0enNxy6Tmf+EntfsUzSt3PmukS91c6VaihdMxWsejvjA8zivj4mDw9yuPio5XkinJDt3JuZA0Zo4BJKYhHjMGFa6XYsclws5ZLdWy1Wro/PRjS1sGsnYqlcqZF6C56qXJqJp4zxW6u3tvABFgR3UwIDAQAB"; public static String decryptByPrivateKey(String encryptAddress){ byte[] bytes = new byte[0]; try { bytes = RSAUtils.decryptByPrivateKey(encryptAddress, private_key); } catch (Exception e) { e.printStackTrace(); } String s = new String(bytes); return s; } } src/main/java/com/xcong/excoin/utils/DES.java
New file @@ -0,0 +1,48 @@ package com.xcong.excoin.utils; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; public class DES { static String string = "DES"; public static void main(String[] args) { DES.jdkDES(); } public static void jdkDES() { try { // 生成key//返回生成指定算法密钥的KeyGenerator对象 KeyGenerator keyGenerator = KeyGenerator.getInstance("DES"); keyGenerator.init(56);//初始化此密钥生成器,使其具有确定的密钥大小 SecretKey secretKey = keyGenerator.generateKey();//生成一个密钥 byte[] bs = secretKey.getEncoded(); // key转换 DESKeySpec desKeySpec = new DESKeySpec(bs); //实例化DES密钥规则 SecretKeyFactory factory = SecretKeyFactory.getInstance("DES"); //实例化密钥工厂 Key convertSecretKey = factory.generateSecret(desKeySpec); //生成密钥 // 加密 Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, convertSecretKey); byte[] result = cipher.doFinal(string.getBytes()); System.out.println("jdk des encrypt:" + DESUtil.byteToHex(result)); // 解密 cipher.init(Cipher.DECRYPT_MODE, convertSecretKey); result = cipher.doFinal(result); System.out.println("jdk des decrypt:" + new String(result)); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } src/main/java/com/xcong/excoin/utils/DESUtil.java
New file @@ -0,0 +1,71 @@ package com.xcong.excoin.utils; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.Formatter; public class DESUtil { /* * 生成密钥 */ public static byte[] initKey() throws Exception{ KeyGenerator keyGen = KeyGenerator.getInstance("DES"); keyGen.init(56); SecretKey secretKey = keyGen.generateKey(); return secretKey.getEncoded(); } /* * DES 加密 */ public static byte[] encrypt(byte[] data, byte[] key) throws Exception{ SecretKey secretKey = new SecretKeySpec(key, "DES"); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] cipherBytes = cipher.doFinal(data); return cipherBytes; } /* * DES 解密 */ public static byte[] decrypt(byte[] data, byte[] key) throws Exception{ SecretKey secretKey = new SecretKeySpec(key, "DES"); Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] plainBytes = cipher.doFinal(data); return plainBytes; } public static String byteToHex(final byte[] hash) { Formatter formatter = new Formatter(); for (byte b : hash) { formatter.format("%02x", b); } String result = formatter.toString(); formatter.close(); return result; } //Test public static void main(String[] args) throws Exception { // byte[] desKey = DESUtil.initKey(); // String da = UUIDUtil.getRandomID(); // System.out.println("DES KEY : " + byteToHex(desKey)); // byte[] desResult = DESUtil.encrypt(da.getBytes(), desKey); // System.out.println(da + ">>>DES 加密结果>>>" + byteToHex(desResult)); // // byte[] desPlain = DESUtil.decrypt(desResult, desKey); // System.out.println(da+ ">>>DES 解密结果>>>" + new String(desPlain)); System.out.println("b68edd21786c4d4816284e2ad6d6291aaf4091cd3a0fc7898f4aa52153d730a32bf17f803a91ffde".length()); } } src/main/java/com/xcong/excoin/utils/MD5Util.java
New file @@ -0,0 +1,55 @@ package com.xcong.excoin.utils; import java.security.MessageDigest; /** * MD5工具类 * * @author jiangyouyao * @email 512061637@qq.com * @date 2019年2月25日 */ public class MD5Util { public static String bytesToHex(byte[] bytes) { StringBuffer md5str = new StringBuffer(); // 把数组每一字节换成16进制连成md5字符串 int digital; for (int i = 0; i < bytes.length; i++) { digital = bytes[i]; if (digital < 0) { digital += 256; } if (digital < 16) { md5str.append("0"); } md5str.append(Integer.toHexString(digital)); } return md5str.toString(); } public static String bytesToMD5(byte[] input) { String md5str = null; try { // 创建一个提供信息摘要算法的对象,初始化为md5算法对象 MessageDigest md = MessageDigest.getInstance("MD5"); // 计算后获得字节数组 byte[] buff = md.digest(input); // 把数组每一字节换成16进制连成md5字符串 md5str = bytesToHex(buff); } catch (Exception e) { e.printStackTrace(); } return md5str; } public static String strToMD5(String str) { byte[] input = str.getBytes(); return bytesToMD5(input); } } src/main/java/com/xcong/excoin/utils/RSAUtils.java
New file @@ -0,0 +1,234 @@ package com.xcong.excoin.utils; import org.apache.commons.codec.binary.Base64; import javax.crypto.Cipher; import java.security.*; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; /** * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2018年5月13日 */ public class RSAUtils { public static final String KEY_ALGORITHM = "RSA"; public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; private static final String PUBLIC_KEY = "RSAPublicKey"; private static final String PRIVATE_KEY = "RSAPrivateKey"; public static byte[] decryptBASE64(String key) { return Base64.decodeBase64(key); } public static String encryptBASE64(byte[] bytes) { return Base64.encodeBase64String(bytes); } /** * 用私钥对信息生成数字签名 * * @param data * 加密数据 * @param privateKey * 私钥 * @return * @throws Exception */ public static String sign(byte[] data, String privateKey) throws Exception { // 解密由base64编码的私钥 byte[] keyBytes = decryptBASE64(privateKey); // 构造PKCS8EncodedKeySpec对象 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取私钥匙对象 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); // 用私钥对信息生成数字签名 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initSign(priKey); signature.update(data); return encryptBASE64(signature.sign()); } /** * 校验数字签名 * * @param data * 加密数据 * @param publicKey * 公钥 * @param sign * 数字签名 * @return 校验成功返回true 失败返回false * @throws Exception */ public static boolean verify(byte[] data, String publicKey, String sign) throws Exception { // 解密由base64编码的公钥 byte[] keyBytes = decryptBASE64(publicKey); // 构造X509EncodedKeySpec对象 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); // KEY_ALGORITHM 指定的加密算法 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); // 取公钥匙对象 PublicKey pubKey = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); signature.initVerify(pubKey); signature.update(data); // 验证签名是否正常 return signature.verify(decryptBASE64(sign)); } public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 解密<br> * 用私钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPrivateKey(String data, String key) throws Exception { return decryptByPrivateKey(decryptBASE64(data), key); } /** * 解密<br> * 用公钥解密 * * @param data * @param key * @return * @throws Exception */ public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } /** * 加密<br> * 用公钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPublicKey(String data, String key) throws Exception { // 对公钥解密 byte[] keyBytes = decryptBASE64(key); // 取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key publicKey = keyFactory.generatePublic(x509KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data.getBytes()); } /** * 加密<br> * 用私钥加密 * * @param data * @param key * @return * @throws Exception */ public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception { // 对密钥解密 byte[] keyBytes = decryptBASE64(key); // 取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec); // 对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } /** * 取得私钥 * * @param keyMap * @return * @throws Exception */ public static String getPrivateKey(Map<String, Key> keyMap) throws Exception { Key key = (Key) keyMap.get(PRIVATE_KEY); return encryptBASE64(key.getEncoded()); } /** * 取得公钥 * * @param keyMap * @return * @throws Exception */ public static String getPublicKey(Map<String, Key> keyMap) throws Exception { Key key = keyMap.get(PUBLIC_KEY); return encryptBASE64(key.getEncoded()); } /** * 初始化密钥 * * @return * @throws Exception */ public static Map<String, Key> initKey() throws Exception { KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); keyPairGen.initialize(1024); KeyPair keyPair = keyPairGen.generateKeyPair(); Map<String, Key> keyMap = new HashMap<>(2); // 公钥 keyMap.put(PUBLIC_KEY, keyPair.getPublic()); // 私钥 keyMap.put(PRIVATE_KEY, keyPair.getPrivate()); return keyMap; } public static void main(String[] args) throws Exception { Map<String, Key> stringKeyMap = initKey(); String publicKey = getPublicKey(stringKeyMap); System.out.println("公钥:"+publicKey); String privateKey = getPrivateKey(stringKeyMap); System.out.println("私钥:"+privateKey); byte[] bytes = encryptByPublicKey("111112323",publicKey); String s = encryptBASE64(bytes); System.out.println("加密后的:"+s); // 解密 byte[] bytes1 = decryptByPrivateKey(s, privateKey); String s1 = new String(bytes1); System.out.println(s1); } } src/main/java/com/xcong/excoin/utils/ToolUtil.java
New file @@ -0,0 +1,362 @@ package com.xcong.excoin.utils; import com.alibaba.fastjson.JSONObject; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.regex.Pattern; /** * 工具类 * @add 20190828 添加时间转换方法 * @author 敢超 * */ public class ToolUtil { private static Logger log = LoggerFactory.getLogger(ToolUtil.class); /* * 字符串正则匹配方法(用于匹配字符串是否包含指定字符串) */ public static boolean stringFilter(String string, String regex) { Pattern p = Pattern.compile(regex); return p.matcher(string).matches(); } /** * 将http传过来的数据转化成实体 * * @param request * @param clazz * @return */ public static <T> T getHttpRequestParams(HttpServletRequest request, Class<T> clazz) { T bean = null; try { bean = clazz.newInstance(); Method[] methods = clazz.getMethods(); for (Method method : methods) { String methodName = method.getName(); if (methodName.startsWith("set")) { String key = methodName.substring(3); key = key.substring(0, 1).toLowerCase() + key.substring(1); String value = request.getParameter(key); if (value != null) { method.invoke(bean, value); } } } } catch (Exception e) { e.printStackTrace(); } return bean; } /** * 实体转json字符串 * @param obj * @return */ public static String objToJson(Object obj) { return JSONObject.toJSONString(obj); } /** * json字符串转对象 * @param json json格式的字符串 * @param clazz * @return */ public static <T> T jsonToObject(String json, Class<T> clazz) { // return new Gson().fromJson(json, clazz); return JSONObject.parseObject(json,clazz); } /** * json转list对象 * @param json * @param clazz * @return */ @SuppressWarnings("unchecked") public static <T> List<T> jsonToList(String json,Class<?> clazz){ return (List<T>) JSONObject.parseArray(json, clazz); } /** * map 对象转bean对象 用于统一处理接口输入参数 * @param map * @param clazz * @param isUpper Map的key值是否为大写类型 ture: USER_ID,false:userId * @return */ public static <T> T mapToBean(Map map, Class<T> clazz, boolean isUpper) { T t = null; try { t = clazz.newInstance(); BeanInfo beanInfo = Introspector.getBeanInfo(clazz); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor property : propertyDescriptors) { String key = property.getName(); if (map.containsKey(key)) { Object value = map.get(key); Method setter = property.getWriteMethod(); if(setter != null && value != null){ if(value.getClass().equals(setter.getParameterTypes()[0])){ setter.invoke(t, value); }else if(Date.class.equals(setter.getParameterTypes()[0]) && Number.class.isAssignableFrom(value.getClass())){ setter.invoke(t,new Date(((Number)value).longValue())); }else { log.warn("【mapToBean】"+key+" 类型不匹配,没有转化"); } }else { log.warn("【mapToBean】"+key+" 不存在写入方法,或值不存在,没有转化"); } } } } catch (Exception e) { e.printStackTrace(); } return t; } /** * 实体bean 转换成map * @param object * @param <T> * @return */ public static <T> Map beanToMap(T object){ Map map = new HashMap(); BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(object.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor property : propertyDescriptors) { String key = property.getName(); if("class".equals(key)){ continue; } Object temp = property.getReadMethod().invoke(object); if(temp != null){ map.put(key,temp); } } } catch (Exception e) { e.printStackTrace(); map = null; } return map; } /** * 大写字母转小写 * @param str USER_ID 转小写 userId * @return */ public static String strToLowerCase(String str) { String s1 = str.toLowerCase(); if (s1.indexOf("_") != -1) { StringBuffer sb = new StringBuffer(); String[] strs = s1.split("_"); for (String temp : strs) { if (sb.length() == 0) { sb.append(temp); } else { char[] cs = temp.toCharArray(); cs[0] -= 32; sb.append(String.valueOf(cs)); } } s1 = sb.toString(); } return s1; } /** * list对象转换成Map<String,T> * @param list 对象 * @param name 作为map的key的 属性 * @return */ public static <T> Map<String, T> listToMap(List<T> list, String name) { HashMap<String, T> map = new HashMap<>(); if(CollectionUtils.isNotEmpty(list)){ try { if(Map.class.isAssignableFrom(list.get(0).getClass())){ for(T object : list){ Map temp = (Map) object; String key = (String) temp.get(name); map.put(key,object); } }else { char[] cs = name.toCharArray(); cs[0] -= 32; String getMethod = "get" + String.valueOf(cs); Method method = list.get(0).getClass().getMethod(getMethod); for (T object : list) { String str = (String) method.invoke(object); map.put(str, object); } } } catch (Exception e) { log.error("listToMap 数据转换出错!"); e.printStackTrace(); } } return map; } /** * 打印异常堆栈 * @param e * @return */ public static String printExceptionDetail(Exception e){ String result = ""; StringWriter sw = null; PrintWriter pw = null; try { sw = new StringWriter(); pw = new PrintWriter(sw); //将出错的栈信息输出到printWriter中 e.printStackTrace(pw); pw.flush(); sw.flush(); result = sw.toString(); } finally { if (sw != null) { try { sw.close(); } catch (IOException e1) { e1.printStackTrace(); } } if (pw != null) { pw.close(); } } return result; } /** * 复制bean属性 * @param source * @param type * @param <T> * @return */ public static <T> T copyBeanProperties(Object source,Class<T> type){ T t = null; try { t = type.newInstance(); PropertyUtils.copyProperties(t,source); } catch (Exception e) { e.printStackTrace(); } return t; } /** * 模拟oracle数据库的decode * @param source * @param match 比配参数,参数个数必须是2的倍数,没有匹配到直接返回原字符串 * @return */ public static String decodeStr(String source,String... match){ if(source == null){ return null; } if(match == null || match.length%2 != 0){ throw new RuntimeException("ToolUtil.decodeStr的match参数错误"); } for(int i = 0;i < match.length;i++){ if(source.equals(match[i])){ return match[i+1]; } i++; } return source; } /** * 根据属性,获取get方法 * @param ob 对象 * @param name 属性名 * @return * @throws Exception */ public static Object getGetMethod(Object ob , String name)throws Exception{ Method[] m = ob.getClass().getMethods(); for(int i = 0;i < m.length;i++){ if(("get"+name).toLowerCase().equals(m[i].getName().toLowerCase())){ return m[i].invoke(ob); } } return null; } /** * 获取格式化后的时间 * @param date * @param pattern * @return */ public static String getStringDate(Date date,String pattern){ SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern); return simpleDateFormat.format(date); } /** * 去除字符串的前后空格 * @author zhangheng * @date 2020-04-23 * @param param * @return java.lang.String */ public static String trimString(String param){ if(StringUtils.isBlank(param)){ return null; } return param.trim(); } public static String listToString(List<String> list,String sep){ if(CollectionUtils.isEmpty(list)){ return null; } int size = list.size(); StringBuilder builder = new StringBuilder(); for(int i=0;i<size;i++){ if(i==0){ builder.append(list.get(i)); }else{ builder.append(sep+list.get(i)); } } return builder.toString(); } } src/main/java/com/xcong/excoin/utils/UUIDUtil.java
New file @@ -0,0 +1,20 @@ package com.xcong.excoin.utils; import java.util.UUID; public class UUIDUtil { /** * 获取一个32位的随机字符串 * * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年11月30日 * @return */ public static String getRandomID() { return UUID.randomUUID().toString().replace("-", ""); } } src/main/java/com/xcong/excoin/utils/WordsUtil.java
New file @@ -0,0 +1,11 @@ package com.xcong.excoin.utils; import java.util.ArrayList; import java.util.List; /** * 助记词 */ public class WordsUtil { public static List<String> words_list = new ArrayList<>(); } src/main/resources/i18n/messages_en_US.properties
@@ -241,3 +241,7 @@ submit_repeat=Do not repeat submission login_init=Cannot generate Wallet login_recovery_001=Please input mnemonics login_recovery_002=Mnemonic errors login_recovery_003=Import succeeded src/main/resources/i18n/messages_zh_CN.properties
@@ -240,3 +240,8 @@ cancellation_fail=撤销失败 submit_repeat=请勿重复提交 login_init=不能生成钱包 login_recovery_001=请输入助记词 login_recovery_002=助记词错误 login_recovery_003=导入成功 src/main/resources/mapper/member/WalletDetailDao.xml
New file @@ -0,0 +1,135 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xcong.excoin.common.system.dao.WalletDetailDao"> <!-- 定义WtWalletDetail 的复杂关联map --> <resultMap type="com.xcong.excoin.common.system.entity.WtWalletDetail" id="WtWalletDetailMap"> <id property="id" column="id"/> <result property="address" column="address"/> <result property="symbol" column="symbol"/> <result property="balance" column="balance"/> <result property="show" column="show"/> </resultMap> <!-- 字段sql --> <sql id="columns"> id, address, symbol, balance, main, is_show </sql> <!-- 属性sql --> <sql id="propertys"> #{item.id}, #{item.address}, #{item.symbol}, #{item.balance}, #{item.main}, #{item.isShow} </sql> <!-- 插入方法 --> <insert id="insert" parameterType="com.xcong.excoin.common.system.entity.WtWalletDetail" useGeneratedKeys="true" keyProperty="item.id"> INSERT INTO wt_wallet_detail ( <include refid="columns"></include> ) VALUES ( <include refid="propertys"></include> ) </insert> <!-- 批量插入 --> <insert id="batchInsert" parameterType="java.util.List"> INSERT INTO wt_wallet_detail ( <include refid="columns"></include> ) VALUES <foreach collection="list" item="item" index="index" separator=",">( <include refid="propertys"></include> ) </foreach> </insert> <!-- 根据对象更新 部分更新 --> <update id="updateByModel" parameterType="String"> UPDATE wt_wallet_detail <set> <if test="record.address != null and record.address != '' "> address = #{record.address}, </if> <if test="record.symbol != null and record.symbol != '' "> symbol = #{record.symbol}, </if> <if test="record.balance != null "> balance = #{record.balance}, </if> <if test="record.isShow != null "> is_show = #{record.isShow}, </if> </set> WHERE id=#{record.id} </update> <!-- 批量删除 --> <delete id="deleteByIds" parameterType="java.util.List"> delete from wt_wallet_detail where id in <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </delete> <!-- 根据id删除--> <delete id="deleteById" parameterType="String"> DELETE FROM wt_wallet_detail where id=#{id} </delete> <!-- 根据id查询--> <select id="selectById" resultMap="WtWalletDetailMap"> select <include refid="columns"></include> from wt_wallet_detail where id=#{id} </select> <select id="selectByAddressAndSymbol" resultMap="WtWalletDetailMap"> select <include refid="columns"></include> from wt_wallet_detail where address=#{address} and symbol = #{symbol} </select> <!-- 根据对象查询--> <select id="selectByModel" resultMap="WtWalletDetailMap"> select <include refid="columns"></include> from wt_wallet_detail <where> <if test="address !=null and address != ''"> and address = #{address} </if> <if test="symbol !=null and symbol != ''"> and symbol = #{symbol} </if> </where> order by main desc </select> <update id="updateWalletBalance" parameterType="map"> update wt_wallet_detail set balance = balance + #{balance} where id = #{id} </update> </mapper> src/main/resources/mapper/member/WtTokenDao.xml
New file @@ -0,0 +1,117 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xcong.excoin.common.system.dao.WtTokenDao"> <!-- 定义WtToken 的复杂关联map --> <!-- 字段sql --> <sql id="columns"> id, symbol, price, main, fee, create_time, amount, contract_address, symbol_name </sql> <!-- 属性sql --> <sql id="propertys"> #{item.id}, #{item.symbol}, #{item.price}, #{item.main}, #{item.fee}, #{item.createTime}, #{item.amount}, #{item.contractAddress}, #{item.symbolName} </sql> <!-- 插入方法 --> <insert id="insert" parameterType="com.xcong.excoin.common.system.entity.WtBlock" useGeneratedKeys="true" keyProperty="item.id"> INSERT INTO wt_token ( <include refid="columns"></include> ) VALUES ( <include refid="propertys"></include> ) </insert> <!-- 批量插入 --> <insert id="batchInsert" parameterType="java.util.List"> INSERT INTO wt_token ( <include refid="columns"></include> ) VALUES <foreach collection="list" item="item" index="index" separator=",">( <include refid="propertys"></include> ) </foreach> </insert> <!-- 根据对象更新 部分更新 --> <update id="updateByModel" parameterType="Integer"> UPDATE wt_token <set> <if test="record.symbol != null and record.symbol != '' "> symbol = #{record.symbol}, </if> <if test="record.price != null "> price = #{record.price}, </if> <if test="record.main != null "> main = #{record.main}, </if> </set> WHERE id=#{record.id} </update> <!-- 根据id删除--> <delete id="deleteById" parameterType="Integer"> DELETE FROM wt_token where id=#{id} </delete> <!-- 根据id查询--> <select id="selectById" resultType="com.xcong.excoin.common.system.entity.WtToken"> select <include refid="columns"></include> from wt_token where id=#{id} </select> <select id="selectBySymbol" resultType="com.xcong.excoin.common.system.entity.WtToken"> select <include refid="columns"></include> from wt_token where symbol =#{symbol} </select> <select id="selectAllToken" resultType="com.xcong.excoin.common.system.entity.WtToken"> select <include refid="columns"></include> from wt_token </select> <select id="selectMainToken" resultType="com.xcong.excoin.common.system.entity.WtToken"> select <include refid="columns"></include> from wt_token where main = 1 </select> </mapper> src/main/resources/mapper/member/WtWalletMapper.xml
New file @@ -0,0 +1,146 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xcong.excoin.common.system.dao.WtWalletDao"> <!-- 定义WtWallet 的复杂关联map --> <resultMap type="com.xcong.excoin.common.system.entity.WtWallet" id="WtWalletMap"> <result property="privateKey" column="private_key" /> <result property="mnemonicWords" column="mnemonic_words" /> <result property="password" column="password" /> <result property="walletName" column="wallet_name" /> <result property="terminalId" column="terminal_Id" /> </resultMap> <!-- 字段sql --> <sql id="columns"> address, private_key, mnemonic_words, password, wallet_name, terminal_Id </sql> <sql id="simpleColumns"> address, wallet_name </sql> <!-- 属性sql --> <sql id="propertys"> #{item.address}, #{item.privateKey}, #{item.mnemonicWords}, #{item.password}, #{item.walletName}, #{item.terminalId} </sql> <!-- 插入方法 --> <insert id="insert" parameterType="com.xcong.excoin.common.system.entity.WtWallet" useGeneratedKeys="true" keyProperty="item.address"> INSERT INTO wt_wallet ( <include refid="columns"></include> ) VALUES ( <include refid="propertys"></include> ) </insert> <!-- 批量插入 --> <insert id="batchInsert" parameterType="java.util.List"> INSERT INTO wt_wallet ( <include refid="columns"></include> ) VALUES <foreach collection="list" item="item" index="index" separator=",">( <include refid="propertys"></include> )</foreach> </insert> <!-- 根据对象更新 部分更新 --> <update id="updateByModel" parameterType="String"> UPDATE wt_wallet <set> <if test="record.password != null and record.password != '' "> password = #{record.password}, </if> <if test="record.walletName != null and record.walletName != '' "> wallet_name = #{record.walletName}, </if> <if test="record.terminalId != null and record.terminalId != '' "> terminal_Id = #{record.terminalId}, </if> </set> WHERE address=#{record.address} </update> <!-- 批量删除 --> <delete id="deleteByIds" parameterType="java.util.List"> delete from wt_wallet where address in <foreach collection="list" index="index" item="item" open="(" separator="," close=")"> #{item} </foreach> </delete> <!-- 根据id删除--> <delete id="deleteById" parameterType="String"> DELETE FROM wt_wallet where address=#{address} </delete> <!-- 根据id查询--> <select id="selectById" resultMap="WtWalletMap"> select <include refid="columns" ></include> from wt_wallet where address=#{address} </select> <select id="selectSimpleById" resultMap="WtWalletMap"> select <include refid="simpleColumns" ></include> from wt_wallet where address=#{address} </select> <select id="selectSimpleByTerminalId" resultMap="WtWalletMap"> select <include refid="simpleColumns" ></include> from wt_wallet where terminal_Id=#{terminalId} limit 1 </select> <select id="selectByMnemonicWords" resultMap="WtWalletMap"> select address, mnemonic_words, wallet_name, terminal_Id from wt_wallet where mnemonic_words=#{mnemonic_words} </select> <update id="clearTerminalId" parameterType="string"> update wt_wallet set terminal_id = null where address = #{address} </update> <update id="deleteTerminal" parameterType="string"> update wt_wallet set terminal_Id = null where terminal_id = #{terminalId} </update> </mapper> src/main/resources/mapper/member/WtWordDao.xml
New file @@ -0,0 +1,9 @@ <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.xcong.excoin.common.system.dao.WtWordDao"> <select id="selectAllWords" resultType="String"> select word from wt_word </select> </mapper>