├── src ├── main │ ├── resources │ │ ├── messages_en_US.properties │ │ ├── logback.xml │ │ ├── shell │ │ │ ├── auto-restart-geth.sh │ │ │ └── auto-restart-geth-rinkeby.sh │ │ ├── messages.properties │ │ ├── messages_zh_CN.properties │ │ └── sql │ │ │ └── mvc_token_sell.sql │ └── java │ │ └── com │ │ └── mvc │ │ └── sell │ │ └── console │ │ ├── common │ │ ├── Page.java │ │ ├── exception │ │ │ └── CheckeException.java │ │ ├── annotation │ │ │ ├── NeedLogin.java │ │ │ └── Check.java │ │ └── interceptor │ │ │ └── ServiceAuthRestInterceptor.java │ │ ├── dao │ │ ├── AdminMapper.java │ │ ├── TransactionMapper.java │ │ ├── AccountMapper.java │ │ ├── ConfigMapper.java │ │ ├── ProjectSoldMapper.java │ │ ├── CapitalMapper.java │ │ ├── OrderMapper.java │ │ └── ProjectMapper.java │ │ ├── pojo │ │ ├── dto │ │ │ ├── HashDTO.java │ │ │ ├── UserFindDTO.java │ │ │ ├── MyProjectDTO.java │ │ │ ├── WithdrawDTO.java │ │ │ ├── TransactionDTO.java │ │ │ ├── OrderDTO.java │ │ │ ├── AdminDTO.java │ │ │ ├── BuyDTO.java │ │ │ └── ProjectDTO.java │ │ ├── bean │ │ │ ├── Capital.java │ │ │ ├── ProjectSold.java │ │ │ ├── Admin.java │ │ │ ├── Account.java │ │ │ ├── Orders.java │ │ │ ├── Config.java │ │ │ ├── Transaction.java │ │ │ └── Project.java │ │ └── vo │ │ │ ├── MyProjectVO.java │ │ │ ├── TokenVO.java │ │ │ ├── ProjectInfoVO.java │ │ │ ├── WithdrawInfoVO.java │ │ │ ├── CapitalVO.java │ │ │ ├── ProjectSoldVO.java │ │ │ ├── ConfigVO.java │ │ │ ├── AccountVO.java │ │ │ ├── OrderVO.java │ │ │ ├── TransactionVO.java │ │ │ └── ProjectVO.java │ │ ├── constants │ │ ├── CommonConstants.java │ │ ├── RedisConstants.java │ │ └── MessageConstants.java │ │ ├── service │ │ ├── ethernum │ │ │ ├── NodeConfiguration.java │ │ │ ├── TransactionResponse.java │ │ │ └── ContractService.java │ │ ├── BaseService.java │ │ ├── AdminService.java │ │ ├── OrderService.java │ │ ├── OssService.java │ │ ├── AccountService.java │ │ ├── ConfigService.java │ │ ├── ProjectService.java │ │ └── TransactionService.java │ │ ├── config │ │ ├── OssConfig.java │ │ ├── SpringContextUtil.java │ │ ├── MyRequestInterceptor.java │ │ ├── CorsConfig.java │ │ ├── MapperConfiguration.java │ │ ├── RedisConfiguration.java │ │ ├── GlobalExceptionHandler.java │ │ ├── LocaleConfig.java │ │ ├── WebConfiguration.java │ │ ├── BeanConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── MybatisConfiguration.java │ │ ├── job │ │ ├── MyStartupRunner.java │ │ ├── ProjectJob.java │ │ └── EthJob.java │ │ ├── TokenSellConsoleBootstrap.java │ │ ├── controller │ │ ├── OrderController.java │ │ ├── BaseController.java │ │ ├── TransactionController.java │ │ ├── ConfigController.java │ │ ├── AdminController.java │ │ ├── AccountController.java │ │ └── ProjectController.java │ │ └── util │ │ ├── Web3jUtil.java │ │ ├── Convert.java │ │ ├── VerifyUtil.java │ │ ├── JwtHelper.java │ │ ├── BeanUtil.java │ │ └── RsaKeyHelper.java └── test │ └── java │ └── com │ └── mvc │ └── sell │ └── console │ └── controller │ ├── OrderControllerTest.java │ ├── TransactionControllerTest.java │ ├── ConfigControllerTest.java │ ├── ProjectControllerTest.java │ ├── AdminControllerTest.java │ ├── BaseTest.java │ └── AccountControllerTest.java ├── .gitignore └── pom.xml /src/main/resources/messages_en_US.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mvchain/token-exchange-protocol-interior/HEAD/src/main/resources/messages_en_US.properties -------------------------------------------------------------------------------- /src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/main/resources/shell/auto-restart-geth.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | kill -9 `ps -ef | grep "geth --rpc"|egrep -v "grep"|awk '{print $2}'` 4 | nohup geth --rpc --rpcaddr 127.0.0.1 --rpccorsdomain "*" --rpcapi "db,eth,net,web3,personal" > /opt/log/geth.log 2>&1 & -------------------------------------------------------------------------------- /src/main/resources/shell/auto-restart-geth-rinkeby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | kill -9 `ps -ef | grep "geth --rpc"|egrep -v "grep"|awk '{print $2}'` 4 | nohup geth --rpc --rpcaddr 127.0.0.1 --rinkeby --rpccorsdomain "*" --rpcapi "db,eth,net,web3,personal" > /opt/log/rinkeby.log 2>&1 & -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/common/Page.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.common; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * page 7 | * 8 | * @author qiyichen 9 | * @create 2018/3/13 16:54 10 | */ 11 | @Data 12 | public class Page { 13 | private Integer pageNum; 14 | private Integer pageSize; 15 | private String orderBy; 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/AdminMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Admin; 4 | import tk.mybatis.mapper.common.Mapper; 5 | 6 | /** 7 | * admin mapper 8 | * 9 | * @author qiyichen 10 | * @create 2018/3/12 14:47 11 | */ 12 | public interface AdminMapper extends Mapper { 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/OrderControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import org.junit.Test; 4 | 5 | public class OrderControllerTest extends BaseTest { 6 | @Test 7 | public void list() throws Exception { 8 | } 9 | 10 | @Test 11 | public void updateStatus() throws Exception { 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .settings 3 | .classpath 4 | .project 5 | 6 | .idea/ 7 | *.iml 8 | *.ipr 9 | *.iws 10 | .gradle/ 11 | build/ 12 | mods/ 13 | .idea/libraries 14 | *.DS_Store 15 | 16 | *.class 17 | 18 | *_blockstore 19 | 20 | # Package Files 21 | # *.jar 22 | *.war 23 | *.ear 24 | 25 | # IDEA 26 | *.iml 27 | .idea/ 28 | .DS_Store 29 | local.* 30 | 31 | application.yml -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/TransactionControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import org.junit.Test; 4 | 5 | public class TransactionControllerTest extends BaseTest { 6 | @Test 7 | public void list() throws Exception { 8 | } 9 | 10 | @Test 11 | public void approval() throws Exception { 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/TransactionMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Transaction; 4 | import tk.mybatis.mapper.common.Mapper; 5 | 6 | /** 7 | * TransactionMapper 8 | * 9 | * @author qiyichen 10 | * @create 2018/3/13 12:07 11 | */ 12 | public interface TransactionMapper extends Mapper { 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/common/exception/CheckeException.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.common.exception; 2 | 3 | /** 4 | * CheckeException 5 | * 6 | * @author qiyichen 7 | * @create 2018/3/12 18:23 8 | */ 9 | public class CheckeException extends Exception { 10 | 11 | public CheckeException() { 12 | super(); 13 | } 14 | 15 | public CheckeException(String msg) { 16 | super(msg); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/HashDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * hash dto 9 | * 10 | * @author qiyichen 11 | * @create 2018/4/16 17:14 12 | */ 13 | @Data 14 | public class HashDTO implements Serializable { 15 | 16 | private static final long serialVersionUID = -206171498299104035L; 17 | 18 | private String hashAddress; 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/constants/CommonConstants.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.constants; 2 | 3 | public interface CommonConstants { 4 | Integer USER_FREEZE = 9; 5 | String ORDER_BUY = "D"; 6 | String ORDER_WITHDRAW = "T"; 7 | String ORDER_RECHARGE = "C"; 8 | Integer WITHDRAW = 1; 9 | Integer RECHARGE = 0; 10 | Integer STATUS_SUCCESS = 2; 11 | Integer ERROR = 9; 12 | Integer ORDER_STATUS_RETIRE = 4; 13 | Integer ORDER_STATUS_SEND_TOKEN = 2; 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/ethernum/NodeConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service.ethernum; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * @author qyc 9 | */ 10 | @Data 11 | @ConfigurationProperties 12 | @Component 13 | public class NodeConfiguration { 14 | 15 | private String nodeEndpoint; 16 | private String fromAddress; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/AccountMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Account; 4 | import org.apache.ibatis.annotations.Select; 5 | import tk.mybatis.mapper.common.Mapper; 6 | 7 | /** 8 | * account mapper 9 | * 10 | * @author qiyichen 11 | * @create 2018/3/12 14:47 12 | */ 13 | public interface AccountMapper extends Mapper { 14 | @Select("select * from account where address_eth is null limit 1") 15 | Account getNonAddress(); 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/ConfigControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import org.junit.Test; 4 | 5 | public class ConfigControllerTest extends BaseTest { 6 | @Test 7 | public void list() throws Exception { 8 | } 9 | 10 | @Test 11 | public void insert() throws Exception { 12 | } 13 | 14 | @Test 15 | public void update() throws Exception { 16 | } 17 | 18 | @Test 19 | public void config() throws Exception { 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Capital.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Id; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * capital 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 17:28 14 | */ 15 | @Data 16 | public class Capital { 17 | @Id 18 | private BigInteger id; 19 | private BigInteger userId; 20 | private BigInteger tokenId; 21 | private BigDecimal balance; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/ProjectSold.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Id; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * token sold 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 19:14 14 | */ 15 | @Data 16 | public class ProjectSold { 17 | @Id 18 | private BigInteger id; 19 | private Integer buyerNum; 20 | private BigDecimal soldEth; 21 | private BigDecimal sendToken; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/common/annotation/NeedLogin.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.common.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * ignore user login check 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/10 17:30 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(value = {ElementType.METHOD, ElementType.TYPE}) 16 | public @interface NeedLogin { 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/ConfigMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Config; 4 | import org.apache.ibatis.annotations.Select; 5 | import tk.mybatis.mapper.common.Mapper; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * config mapper 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/12 14:47 14 | */ 15 | public interface ConfigMapper extends Mapper { 16 | @Select("select token_name from config where need_show = 1 and withdraw_status = 1") 17 | List token(); 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Admin.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigInteger; 6 | import java.util.Date; 7 | 8 | /** 9 | * admin 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/12 14:50 13 | */ 14 | @Data 15 | public class Admin { 16 | 17 | private BigInteger id; 18 | private String username; 19 | private String password; 20 | private Integer status; 21 | private String headImage; 22 | private Date createdAt; 23 | private Date updateAt; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/common/annotation/Check.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.common.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * auto check before service 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/10 17:30 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target(value = {ElementType.METHOD, ElementType.TYPE}) 16 | public @interface Check { 17 | 18 | String[] type(); 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/UserFindDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import com.mvc.sell.console.common.Page; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * UserFindDTO 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/12 20:34 14 | */ 15 | @Data 16 | public class UserFindDTO extends Page implements Serializable { 17 | private static final long serialVersionUID = 5483965417840093756L; 18 | 19 | private String username; 20 | private BigInteger id; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/MyProjectVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | 8 | /** 9 | * MyProjectVO 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/14 19:08 13 | */ 14 | @Data 15 | public class MyProjectVO extends ProjectVO implements Serializable { 16 | private static final long serialVersionUID = -3075200194863929308L; 17 | 18 | private Boolean partake; 19 | private BigDecimal soldEth; 20 | private Integer buyerNum; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/MyProjectDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import com.mvc.sell.console.common.Page; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * @author qiyichen 11 | * @create 2018/3/14 19:06 12 | */ 13 | @Data 14 | public class MyProjectDTO extends Page implements Serializable { 15 | private static final long serialVersionUID = -4568956783195995014L; 16 | 17 | private BigInteger id; 18 | private BigInteger userId; 19 | private Integer status; 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/TokenVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.NoArgsConstructor; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | * token vo 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/12 14:48 14 | */ 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class TokenVO implements Serializable { 19 | 20 | 21 | private static final long serialVersionUID = -2962447657047492746L; 22 | 23 | private String token; 24 | private String refreshToken; 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/constants/RedisConstants.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.constants; 2 | 3 | public interface RedisConstants { 4 | 5 | 6 | String USER_STATUS = "USER_STATUS"; 7 | String USER_PROJECTS = "USER_PROJECTS"; 8 | String TODAY_USER = "TODAY_USER"; 9 | String LISTEN_ETH_ADDR = "LISTEN_ETH_ADDR"; 10 | String LISTEN_HASH = "LISTEN_HASH"; 11 | String WITHDRAW_ETH_HASH = "WITHDRAW_ETH_HASH"; 12 | 13 | String UNIT = "UNIT"; 14 | String LAST_BOLCK_NUMBER = "LAST_BOLCK_NUMBER"; 15 | String GAS_QUENE = "GAS_QUENE"; 16 | String ORDER_LOCK = "ORDER_LOCK"; 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/WithdrawDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | 8 | /** 9 | * WithdrawDTO 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/15 15:20 13 | */ 14 | @Data 15 | public class WithdrawDTO implements Serializable { 16 | private static final long serialVersionUID = -5364677919189328904L; 17 | 18 | private String address; 19 | private BigDecimal number; 20 | private String emailCode; 21 | private String transactionPassword; 22 | private String tokenName; 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/ProjectInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * project info vo 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/15 14:04 14 | */ 15 | @Data 16 | public class ProjectInfoVO implements Serializable { 17 | private static final long serialVersionUID = 6633458831706692961L; 18 | 19 | private BigInteger projectId; 20 | private String tokenName; 21 | private BigDecimal ethBalance; 22 | private Float ratio; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/WithdrawInfoVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | 8 | /** 9 | * WithdrawInfo vo 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/15 14:51 13 | */ 14 | @Data 15 | public class WithdrawInfoVO implements Serializable { 16 | private static final long serialVersionUID = -8264574570847638003L; 17 | private BigDecimal balance; 18 | private String tokenName; 19 | private float min; 20 | private float max; 21 | private float poundage; 22 | private BigDecimal todayUse; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/TransactionDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import com.mvc.sell.console.common.Page; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * TransactionDTO 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 12:06 14 | */ 15 | @Data 16 | public class TransactionDTO extends Page implements Serializable { 17 | private static final long serialVersionUID = 7753553107052784799L; 18 | 19 | private BigInteger userId; 20 | private String orderId; 21 | private Integer type; 22 | private Integer status; 23 | private BigInteger tokenId; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/ethernum/TransactionResponse.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service.ethernum; 2 | 3 | import lombok.Getter; 4 | import lombok.Setter; 5 | 6 | /** 7 | * @author qyc 8 | */ 9 | @Getter 10 | @Setter 11 | public class TransactionResponse { 12 | 13 | private String transactionHash; 14 | private T event; 15 | 16 | TransactionResponse() { 17 | } 18 | 19 | public TransactionResponse(String transactionHash) { 20 | this(transactionHash, null); 21 | } 22 | 23 | public TransactionResponse(String transactionHash, T event) { 24 | this.transactionHash = transactionHash; 25 | this.event = event; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/CapitalVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * Capital vo 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 17:36 14 | */ 15 | @Data 16 | public class CapitalVO implements Serializable { 17 | 18 | private static final long serialVersionUID = 5197644464494680255L; 19 | 20 | private BigInteger id; 21 | private BigInteger tokenId; 22 | private BigDecimal balance; 23 | private String tokenName; 24 | private Integer rechargeStatus; 25 | private Integer withdrawStatus; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/OrderDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import com.mvc.sell.console.common.Page; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * OrderDTO 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 11:47 14 | */ 15 | @Data 16 | public class OrderDTO extends Page implements Serializable { 17 | private static final long serialVersionUID = 2072598127090643637L; 18 | 19 | private BigInteger id; 20 | private BigInteger orderId; 21 | private BigInteger userId; 22 | private BigInteger projectId; 23 | private Integer orderStatus; 24 | private Integer status; 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Account.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Id; 6 | import java.math.BigInteger; 7 | import java.util.Date; 8 | 9 | /** 10 | * Account 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/12 20:38 14 | */ 15 | @Data 16 | public class Account { 17 | @Id 18 | private BigInteger id; 19 | private String username; 20 | private Date createdAt; 21 | private Date updateAt; 22 | private Integer status; 23 | private String password; 24 | private String transactionPassword; 25 | private String phone; 26 | private Integer orderNum; 27 | private String addressEth; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/AdminDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import com.mvc.sell.console.constants.MessageConstants; 4 | import lombok.Data; 5 | 6 | import javax.validation.constraints.NotNull; 7 | import java.io.Serializable; 8 | 9 | /** 10 | * admin dto 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/12 14:43 14 | */ 15 | @Data 16 | public class AdminDTO implements Serializable { 17 | private static final long serialVersionUID = -1840405735682750834L; 18 | 19 | @NotNull(message = "{USERNAME_EMPTY}") 20 | private String username; 21 | 22 | @NotNull(message = "{PWD_EMPTY}") 23 | private String password; 24 | 25 | private String imageCode; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Orders.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Id; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | import java.util.Date; 9 | 10 | /** 11 | * Orders 12 | * 13 | * @author qiyichen 14 | * @create 2018/3/13 11:57 15 | */ 16 | @Data 17 | public class Orders { 18 | @Id 19 | private BigInteger id; 20 | private String orderId; 21 | private Date createdAt; 22 | private Date updatedAt; 23 | private BigInteger userId; 24 | private BigInteger projectId; 25 | private BigDecimal ethNumber; 26 | private BigDecimal tokenNumber; 27 | private Integer orderStatus; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/ProjectSoldVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | 9 | /** 10 | * ProjectSoldVO vo 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/14 14:56 14 | */ 15 | @Data 16 | public class ProjectSoldVO implements Serializable { 17 | private static final long serialVersionUID = 1185097066226411335L; 18 | 19 | private BigInteger id; 20 | private Integer buyerNum; 21 | private BigDecimal soldEth; 22 | private BigDecimal sendToken; 23 | private BigDecimal ethNumber; 24 | private BigDecimal tokenNumber; 25 | private String tokenName; 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/constants/MessageConstants.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.constants; 2 | 3 | import org.springframework.context.i18n.LocaleContextHolder; 4 | import org.springframework.stereotype.Component; 5 | 6 | import java.util.Locale; 7 | import java.util.ResourceBundle; 8 | 9 | /** 10 | * @author qiyichen 11 | * @create 2018/3/12 14:45 12 | */ 13 | @Component 14 | public class MessageConstants { 15 | 16 | public static Integer TOKEN_EXPIRE_CODE = 50014; 17 | public static Integer TOKEN_ERROR_CODE = 50015; 18 | 19 | public static String getMsg(String key) { 20 | Locale locale = LocaleContextHolder.getLocale(); 21 | ResourceBundle bundle = ResourceBundle.getBundle("messages", locale); 22 | return bundle.getString(key); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/ConfigVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigInteger; 7 | import java.util.Date; 8 | 9 | /** 10 | * Config vo 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/14 11:04 14 | */ 15 | @Data 16 | public class ConfigVO implements Serializable { 17 | private static final long serialVersionUID = -1908092063796472159L; 18 | 19 | private BigInteger id; 20 | private int rechargeStatus; 21 | private int withdrawStatus; 22 | private float min; 23 | private float max; 24 | private float poundage; 25 | private Date createdAt; 26 | private Date updatedAt; 27 | private BigInteger projectId; 28 | private String tokenName; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/AccountVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigInteger; 7 | import java.util.Date; 8 | 9 | /** 10 | * AccountVO 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 10:52 14 | */ 15 | @Data 16 | public class AccountVO implements Serializable { 17 | private static final long serialVersionUID = 8363134325804839458L; 18 | 19 | private BigInteger id; 20 | private String username; 21 | private Date createdAt; 22 | private Date updateAt; 23 | private Integer status; 24 | private String phone; 25 | private Integer orderNum; 26 | private String password; 27 | private String transactionPassword; 28 | private String addressEth; 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Config.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Id; 6 | import java.math.BigInteger; 7 | import java.util.Date; 8 | 9 | /** 10 | * Config 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/13 11:04 14 | */ 15 | @Data 16 | public class Config { 17 | @Id 18 | private BigInteger id; 19 | /** 1 - available */ 20 | private Integer rechargeStatus; 21 | /** 1 - available */ 22 | private Integer withdrawStatus; 23 | private Float min; 24 | private Float max; 25 | private Float poundage; 26 | private Date createdAt; 27 | private Date updatedAt; 28 | private String tokenName; 29 | private Integer needShow; 30 | private String contractAddress; 31 | private Integer decimals; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/BuyDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import com.mvc.sell.console.constants.MessageConstants; 4 | import lombok.Data; 5 | 6 | import javax.validation.constraints.DecimalMin; 7 | import javax.validation.constraints.Digits; 8 | import java.io.Serializable; 9 | import java.math.BigDecimal; 10 | import java.math.BigInteger; 11 | 12 | /** 13 | * BuyDTO 14 | * 15 | * @author qiyichen 16 | * @create 2018/3/15 14:21 17 | */ 18 | @Data 19 | public class BuyDTO implements Serializable { 20 | 21 | private static final long serialVersionUID = 3760227948938685745L; 22 | 23 | private BigInteger projectId; 24 | @DecimalMin(value = "0.1", message = "{ETH_MIN}") 25 | @Digits(integer = 10, fraction = 1, message = "{DIGIT_ERR}") 26 | private BigDecimal ethNumber; 27 | private String transactionPassword; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/OssConfig.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import com.aliyun.oss.OSSClient; 4 | import org.springframework.beans.factory.annotation.Value; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * oss config 10 | * 11 | * @author qiyichen 12 | * @create 2018/3/16 10:33 13 | */ 14 | @Configuration 15 | public class OssConfig { 16 | @Value("${oss.endpoint}") 17 | private String endpoint; 18 | @Value("${oss.accessKeyId}") 19 | private String accessKeyId; 20 | @Value("${oss.accessKeySecret}") 21 | private String accessKeySecret; 22 | @Value("${oss.bucketName}") 23 | private String bucketName; 24 | 25 | @Bean 26 | OSSClient ossClient() { 27 | return new OSSClient(endpoint, accessKeyId, accessKeySecret); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/SpringContextUtil.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.BeanFactory; 5 | import org.springframework.beans.factory.BeanFactoryAware; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Component 10 | @Configuration 11 | public class SpringContextUtil implements BeanFactoryAware { 12 | private static BeanFactory beanFactory; 13 | 14 | @Override 15 | public void setBeanFactory(BeanFactory beanFactory) throws BeansException { 16 | SpringContextUtil.beanFactory = beanFactory; 17 | } 18 | 19 | public static T getBean(String beanName) { 20 | if (null != beanFactory) { 21 | return (T) beanFactory.getBean(beanName); 22 | } 23 | return null; 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Transaction.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Id; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | import java.util.Date; 9 | 10 | /** 11 | * transaction 12 | * 13 | * @author qiyichen 14 | * @create 2018/3/13 12:03 15 | */ 16 | @Data 17 | public class Transaction { 18 | 19 | @Id 20 | private BigInteger id; 21 | private BigInteger userId; 22 | private String orderId; 23 | private Float poundage; 24 | private Date startAt; 25 | private Date finishAt; 26 | private Date createdAt; 27 | private Date updatedAt; 28 | private BigDecimal number; 29 | private BigDecimal realNumber; 30 | private BigInteger tokenId; 31 | private String fromAddress; 32 | private String toAddress; 33 | private String hash; 34 | private Integer status; 35 | private Integer type; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/job/MyStartupRunner.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.job; 2 | 3 | import com.mvc.sell.console.service.TransactionService; 4 | import lombok.extern.java.Log; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.boot.CommandLineRunner; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.scheduling.annotation.Async; 9 | import org.springframework.stereotype.Component; 10 | 11 | /** 12 | * @author qyc 13 | */ 14 | @Component 15 | @Order(value = 1) 16 | @Log 17 | public class MyStartupRunner implements CommandLineRunner { 18 | 19 | @Autowired 20 | TransactionService transactionService; 21 | 22 | 23 | @Override 24 | @Async 25 | public void run(String... args) throws InterruptedException { 26 | transactionService.initConfig(); 27 | transactionService.startHistory(); 28 | transactionService.startListen(); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/MyRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import com.mvc.common.context.BaseContextHandler; 4 | import feign.RequestInterceptor; 5 | import feign.RequestTemplate; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | 9 | /** 10 | * bean confing 11 | * 12 | * @author qiyichen 13 | * @create 2018/3/12 19:38 14 | */ 15 | @Configuration 16 | public class MyRequestInterceptor { 17 | 18 | @Bean 19 | public RequestInterceptor headerInterceptor() { 20 | return new RequestInterceptor() { 21 | @Override 22 | public void apply(RequestTemplate requestTemplate) { 23 | String token = (String) BaseContextHandler.get("Authorization"); 24 | requestTemplate.header("Authorization", token); 25 | requestTemplate.header("type", "feign"); 26 | } 27 | }; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/job/ProjectJob.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.job; 2 | 3 | import com.mvc.sell.console.service.ProjectService; 4 | import lombok.extern.log4j.Log4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Component; 8 | import org.web3j.protocol.Web3j; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * eth job 14 | * 15 | * @author qiyichen 16 | * @create 2018/3/16 14:20 17 | */ 18 | @Component 19 | @Log4j 20 | public class ProjectJob { 21 | 22 | @Autowired 23 | ProjectService projectService; 24 | @Autowired 25 | Web3j web3j; 26 | 27 | @Scheduled(cron = "*/1 * * * * ?") 28 | public void updateStatus() throws IOException { 29 | Integer num = projectService.updateStatus(); 30 | if (num > 0) { 31 | log.info(String.format("%s project update status", num)); 32 | } 33 | } 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/OrderVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | import java.util.Date; 9 | 10 | /** 11 | * OrderVO 12 | * 13 | * @author qiyichen 14 | * @create 2018/3/13 12:00 15 | */ 16 | @Data 17 | public class OrderVO implements Serializable { 18 | private static final long serialVersionUID = 4830776689679004765L; 19 | 20 | 21 | private BigInteger id; 22 | private String orderId; 23 | private Date createdAt; 24 | private Date updatedAt; 25 | private BigInteger userId; 26 | private BigInteger projectId; 27 | private BigDecimal ethNumber; 28 | private BigDecimal tokenNumber; 29 | private Integer orderStatus; 30 | private String projectName; 31 | private Integer status; 32 | private Integer retire; 33 | private Integer sendToken; 34 | private BigDecimal projectEthNumber; 35 | private BigDecimal soldEth; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/TokenSellConsoleBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console; 2 | 3 | import org.springframework.boot.autoconfigure.SpringBootApplication; 4 | import org.springframework.boot.builder.SpringApplicationBuilder; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | import org.springframework.scheduling.annotation.EnableAsync; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | import org.springframework.transaction.annotation.EnableTransactionManagement; 9 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 10 | 11 | /** 12 | * ${DESCRIPTION} 13 | * 14 | * @author wanghaobin 15 | * @create 2017-05-25 12:44 16 | */ 17 | @EnableEurekaClient 18 | @SpringBootApplication 19 | @EnableScheduling 20 | @EnableAsync 21 | @EnableTransactionManagement 22 | @EnableSwagger2 23 | public class TokenSellConsoleBootstrap { 24 | public static void main(String[] args) { 25 | new SpringApplicationBuilder(TokenSellConsoleBootstrap.class).web(true).run(args); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/TransactionVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | import java.util.Date; 9 | 10 | /** 11 | * Transaction vo 12 | * 13 | * @author qiyichen 14 | * @create 2018/3/13 12:09 15 | */ 16 | @Data 17 | public class TransactionVO implements Serializable { 18 | private static final long serialVersionUID = -3765613393191632039L; 19 | 20 | private BigInteger id; 21 | private BigInteger userId; 22 | private String orderId; 23 | private Float poundage; 24 | private Date startAt; 25 | private Date finishAt; 26 | private Date createdAt; 27 | private Date updatedAt; 28 | private BigDecimal number; 29 | private BigInteger realNumber; 30 | private BigInteger tokenId; 31 | private String fromAddress; 32 | private String toAddress; 33 | private String hash; 34 | private Integer status; 35 | private Integer type; 36 | private String tokenName; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/ProjectSoldMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.ProjectSold; 4 | import com.mvc.sell.console.pojo.vo.ProjectSoldVO; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | import org.apache.ibatis.annotations.Update; 8 | import tk.mybatis.mapper.common.Mapper; 9 | 10 | import java.math.BigDecimal; 11 | import java.math.BigInteger; 12 | 13 | /** 14 | * token sold mapper 15 | * 16 | * @author qiyichen 17 | * @create 2018/3/13 19:14 18 | */ 19 | public interface ProjectSoldMapper extends Mapper { 20 | @Select("select t2.*, t1.token_name, t1.eth_number, t1.ratio * t1.eth_number token_number from project t1, project_sold t2 where t1.id = t2.id and t1.id = #{id}") 21 | ProjectSoldVO selectSold(ProjectSold projectSold); 22 | 23 | @Update("update project_sold set sold_eth = sold_eth - #{ethNumber} where id = #{projectId}") 24 | void updateEth(@Param("projectId") BigInteger projectId, @Param("ethNumber") BigDecimal ethNumber); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/dto/ProjectDTO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.dto; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | import java.util.Date; 9 | 10 | /** 11 | * Project dto 12 | * 13 | * @author qiyichen 14 | * @create 2018/3/13 18:12 15 | */ 16 | @Data 17 | public class ProjectDTO implements Serializable { 18 | 19 | private static final long serialVersionUID = -4469141542284477495L; 20 | private BigInteger id; 21 | private String title; 22 | private String tokenName; 23 | private String contractAddress; 24 | private BigDecimal ethNumber; 25 | private Float ratio; 26 | private Date startTime; 27 | private Date stopTime; 28 | private String homepage; 29 | private String whitePaperAddress; 30 | private String whitePaperName; 31 | private String projectImageAddress; 32 | private String projectImageName; 33 | private String projectCoverAddress; 34 | private String projectCoverName; 35 | private String leaderImageAddress; 36 | private String leaderImageName; 37 | private String leaderName; 38 | private String position; 39 | private String description; 40 | private Integer decimals; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/job/EthJob.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.job; 2 | 3 | import com.mvc.sell.console.service.TransactionService; 4 | import lombok.extern.log4j.Log4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Component; 8 | import org.web3j.protocol.Web3j; 9 | 10 | import java.io.IOException; 11 | 12 | /** 13 | * eth job 14 | * 15 | * @author qiyichen 16 | * @create 2018/3/16 14:20 17 | */ 18 | @Component 19 | @Log4j 20 | public class EthJob { 21 | 22 | @Autowired 23 | TransactionService transactionService; 24 | @Autowired 25 | Web3j web3j; 26 | 27 | @Scheduled(cron = "*/10 * * * * ?") 28 | public void updateAddress() throws IOException { 29 | Integer num = transactionService.newAddress(); 30 | if (num > 0) { 31 | log.info(String.format("%s user update eth address", num)); 32 | } 33 | } 34 | 35 | @Scheduled(cron = "*/30 * * * * ?") 36 | public void sendGas() throws IOException { 37 | Integer num = transactionService.sendGas(); 38 | if (num > 0) { 39 | log.info(String.format("%s address send gas ", num)); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/CorsConfig.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import org.springframework.beans.factory.annotation.Value; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.cors.CorsConfiguration; 7 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 8 | 9 | /** 10 | * @author qyc 11 | */ 12 | @Configuration 13 | public class CorsConfig { 14 | 15 | @Value("${cors.allowedOrigin}") 16 | private String allowedOrigin; 17 | 18 | private CorsConfiguration buildConfig() { 19 | CorsConfiguration corsConfiguration = new CorsConfiguration(); 20 | corsConfiguration.addAllowedOrigin(allowedOrigin); 21 | corsConfiguration.addAllowedHeader("*"); 22 | corsConfiguration.addAllowedMethod("*"); 23 | corsConfiguration.setAllowCredentials(true); 24 | return corsConfiguration; 25 | } 26 | 27 | @Bean 28 | public org.springframework.web.filter.CorsFilter corsFilter() { 29 | UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 30 | source.registerCorsConfiguration("/**", buildConfig()); 31 | return new org.springframework.web.filter.CorsFilter(source); 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/CapitalMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Capital; 4 | import com.mvc.sell.console.pojo.vo.CapitalVO; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | import org.apache.ibatis.annotations.Update; 8 | import tk.mybatis.mapper.common.Mapper; 9 | 10 | import java.math.BigDecimal; 11 | import java.math.BigInteger; 12 | import java.util.List; 13 | 14 | /** 15 | * CapitalMapper 16 | * 17 | * @author qiyichen 18 | * @create 2018/3/13 17:31 19 | */ 20 | public interface CapitalMapper extends Mapper { 21 | @Select("SELECT t2.*, t2.id token_id, IFNULL(t1.balance,0) balance FROM capital t1 RIGHT JOIN config t2 ON t1.token_id = t2.id and t1.user_id = #{userId} WHERE t2.need_show = 1") 22 | List selectBalance(Capital capital); 23 | 24 | @Update("update capital set balance = balance + #{balance} where user_id = #{userId} and token_id = #{tokenId}") 25 | void updateBalance(@Param("userId") BigInteger userId, @Param("tokenId") BigInteger tokenId, @Param("balance") BigDecimal balance); 26 | 27 | @Update("update capital set balance = balance - #{ethNumber} where user_id = #{userId} and token_id = 0 and balance >= #{ethNumber}") 28 | Integer updateEth(@Param("userId") BigInteger userId, @Param("ethNumber") BigDecimal ethNumber); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/OrderController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.common.msg.Result; 5 | import com.mvc.common.msg.ResultGenerator; 6 | import com.mvc.sell.console.common.annotation.NeedLogin; 7 | import com.mvc.sell.console.pojo.dto.OrderDTO; 8 | import com.mvc.sell.console.pojo.vo.OrderVO; 9 | import io.swagger.annotations.ApiOperation; 10 | import org.springframework.web.bind.annotation.*; 11 | 12 | import javax.validation.Valid; 13 | import java.math.BigInteger; 14 | 15 | /** 16 | * order controller 17 | * 18 | * @author qiyichen 19 | * @create 2018/3/10 17:25 20 | */ 21 | @RestController 22 | @RequestMapping("order") 23 | public class OrderController extends BaseController { 24 | 25 | @ApiOperation("查询订单.status: 取消 = 9, 默认0,已发币2,已清退4") 26 | @GetMapping 27 | @NeedLogin 28 | Result> list(@ModelAttribute @Valid OrderDTO orderDTO) { 29 | return ResultGenerator.genSuccessResult(orderService.list(orderDTO)); 30 | } 31 | 32 | @ApiOperation("取消订单9,目前手动传入方便后续扩展") 33 | @PutMapping("{orderId}/orderStatus/{orderStatus}") 34 | @NeedLogin 35 | Result updateStatus(@PathVariable BigInteger orderId, @PathVariable Integer orderStatus) { 36 | orderService.updateStatus(orderId, orderStatus); 37 | return ResultGenerator.genSuccessResult(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/bean/Project.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.bean; 2 | 3 | import com.mvc.sell.console.constants.MessageConstants; 4 | import lombok.Data; 5 | 6 | import javax.persistence.Id; 7 | import javax.validation.constraints.NotNull; 8 | import java.math.BigDecimal; 9 | import java.math.BigInteger; 10 | import java.util.Date; 11 | 12 | /** 13 | * Project 14 | * 15 | * @author qiyichen 16 | * @create 2018/3/13 11:17 17 | */ 18 | @Data 19 | public class Project { 20 | @Id 21 | private BigInteger id; 22 | @NotNull(message = "{TITLE_EMPTY}") 23 | private String title; 24 | private String tokenName; 25 | private BigDecimal ethNumber; 26 | private Float ratio; 27 | private Date startTime; 28 | private Date stopTime; 29 | private String whitePaperAddress; 30 | private String whitePaperName; 31 | private String homepage; 32 | private String projectImageAddress; 33 | private String projectImageName; 34 | private String projectCoverAddress; 35 | private String projectCoverName; 36 | private String leaderImageAddress; 37 | private String leaderImageName; 38 | private String leaderName; 39 | private String position; 40 | private String description; 41 | private Date createdAt; 42 | private Date updatedAt; 43 | private Integer status; 44 | private Integer needShow; 45 | private Integer sendToken; 46 | private Integer retire; 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/pojo/vo/ProjectVO.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.pojo.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.math.BigDecimal; 7 | import java.math.BigInteger; 8 | import java.util.Date; 9 | 10 | /** 11 | * ProjectVO 12 | * 13 | * @author qiyichen 14 | * @create 2018/3/13 11:28 15 | */ 16 | @Data 17 | public class ProjectVO implements Serializable { 18 | private static final long serialVersionUID = -42092415251737822L; 19 | 20 | private BigInteger id; 21 | private String title; 22 | private String tokenName; 23 | private String contractAddress; 24 | private BigDecimal ethNumber; 25 | private Float ratio; 26 | private Date startTime; 27 | private Date stopTime; 28 | private String whitePaperAddress; 29 | private String whitePaperName; 30 | private String homepage; 31 | private String projectImageAddress; 32 | private String projectImageName; 33 | private String projectCoverAddress; 34 | private String projectCoverName; 35 | private String leaderImageAddress; 36 | private String leaderImageName; 37 | private String leaderName; 38 | private String position; 39 | private String description; 40 | private Date createdAt; 41 | private Date updatedAt; 42 | private Integer decimals; 43 | private Integer needShow; 44 | private Integer sendToken; 45 | private Integer retire; 46 | private Integer status; 47 | 48 | private Integer tokenWithdrawStatus; 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/ProjectControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import org.junit.Test; 4 | 5 | public class ProjectControllerTest extends BaseTest { 6 | @Test 7 | public void list() throws Exception { 8 | } 9 | 10 | @Test 11 | public void add() throws Exception { 12 | } 13 | 14 | @Test 15 | public void update() throws Exception { 16 | } 17 | 18 | @Test 19 | public void get() throws Exception { 20 | } 21 | 22 | @Test 23 | public void sold() throws Exception { 24 | } 25 | 26 | @Test 27 | public void doGetSignature() throws Exception { 28 | } 29 | 30 | @Test 31 | public void show() throws Exception { 32 | } 33 | 34 | @Test 35 | public void sendToken() throws Exception { 36 | } 37 | 38 | @Test 39 | public void retire() throws Exception { 40 | } 41 | 42 | @Test 43 | public void retire1() throws Exception { 44 | } 45 | 46 | @Test 47 | public void get1() throws Exception { 48 | } 49 | 50 | @Test 51 | public void getByUser() throws Exception { 52 | } 53 | 54 | @Test 55 | public void getListByUser() throws Exception { 56 | } 57 | 58 | @Test 59 | public void info() throws Exception { 60 | } 61 | 62 | @Test 63 | public void buy() throws Exception { 64 | } 65 | 66 | @Test 67 | public void getWithdrawConfig() throws Exception { 68 | } 69 | 70 | @Test 71 | public void withdraw() throws Exception { 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.mvc.sell.console.constants.MessageConstants; 4 | import com.mvc.sell.console.service.*; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.context.MessageSource; 7 | import org.springframework.data.redis.core.RedisTemplate; 8 | import org.springframework.stereotype.Component; 9 | import org.springframework.stereotype.Controller; 10 | 11 | /** 12 | * base controller 13 | * 14 | * @author qiyichen 15 | * @create 2018/3/10 16:44 16 | */ 17 | @Controller 18 | public class BaseController { 19 | 20 | @Autowired 21 | AdminService adminService; 22 | @Autowired 23 | OrderService orderService; 24 | @Autowired 25 | ProjectService projectService; 26 | @Autowired 27 | AccountService accountService; 28 | @Autowired 29 | TransactionService transactionService; 30 | @Autowired 31 | ConfigService configService; 32 | @Autowired 33 | OssService ossService; 34 | @Autowired 35 | RedisTemplate redisTemplate; 36 | 37 | void check(String user, String type, String valiCode) throws IllegalAccessException { 38 | String code = (String) redisTemplate.opsForValue().get(type + "Check" + user); 39 | if (null == valiCode || !valiCode.equalsIgnoreCase(code)) { 40 | throw new IllegalAccessException(MessageConstants.getMsg("VALI_CODE_ERR")); 41 | } else { 42 | redisTemplate.delete(type + "Check" + user); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/MapperConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.boot.bind.RelaxedPropertyResolver; 6 | import org.springframework.context.EnvironmentAware; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.core.env.Environment; 10 | import tk.mybatis.spring.mapper.MapperScannerConfigurer; 11 | 12 | /** 13 | * mybatis mapper 扫描配置类 14 | * 15 | * @author wanghaobin 16 | * @date 2016年12月15日 17 | * @since 1.7 18 | */ 19 | @Configuration 20 | @AutoConfigureAfter(MybatisConfiguration.class) 21 | public class MapperConfiguration implements EnvironmentAware { 22 | 23 | private RelaxedPropertyResolver propertyResolver; 24 | 25 | private String basePackage; 26 | 27 | @Bean 28 | public MapperScannerConfigurer mapperScannerConfigurer(Environment environment) { 29 | 30 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 31 | mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory"); 32 | mapperScannerConfigurer.setBasePackage(basePackage); 33 | return mapperScannerConfigurer; 34 | } 35 | 36 | 37 | @Override 38 | public void setEnvironment(Environment environment) { 39 | this.propertyResolver = new RelaxedPropertyResolver(environment, null); 40 | this.basePackage = propertyResolver.getProperty("mybatis.basepackage"); 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/TransactionController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.common.msg.Result; 5 | import com.mvc.common.msg.ResultGenerator; 6 | import com.mvc.sell.console.common.annotation.NeedLogin; 7 | import com.mvc.sell.console.pojo.dto.HashDTO; 8 | import com.mvc.sell.console.pojo.dto.TransactionDTO; 9 | import com.mvc.sell.console.pojo.vo.TransactionVO; 10 | import io.swagger.annotations.ApiOperation; 11 | import org.springframework.web.bind.annotation.*; 12 | 13 | import javax.validation.Valid; 14 | import java.math.BigInteger; 15 | 16 | /** 17 | * transaction controller 18 | * 19 | * @author qiyichen 20 | * @create 2018/3/10 17:12 21 | */ 22 | @RestController 23 | @RequestMapping("transaction") 24 | public class TransactionController extends BaseController { 25 | 26 | @ApiOperation("查询冲提记录") 27 | @GetMapping 28 | @NeedLogin 29 | Result> list(@ModelAttribute @Valid TransactionDTO transactionDTO) { 30 | return ResultGenerator.genSuccessResult(transactionService.transaction(transactionDTO)); 31 | } 32 | 33 | @ApiOperation("更新冲提状态 0待审核, 1等待提币(同意,同意后会直接发送,成功后刷新列表可看到hash), 2成功, 9拒绝") 34 | @PutMapping("{id}/status/{status}") 35 | @NeedLogin 36 | Result approval(@PathVariable BigInteger id, @PathVariable Integer status, @RequestBody HashDTO hashDTO) throws Exception { 37 | transactionService.approval(id, status, hashDTO.getHashAddress()); 38 | return ResultGenerator.genSuccessResult(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/RedisConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.data.redis.connection.RedisConnectionFactory; 9 | import org.springframework.data.redis.core.RedisTemplate; 10 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 11 | 12 | /** 13 | * ${DESCRIPTION} 14 | * 15 | * @author wanghaobin 16 | * @create 2017-06-21 8:39 17 | */ 18 | 19 | @Configuration 20 | public class RedisConfiguration { 21 | 22 | @Bean 23 | public RedisTemplate redisTemplate(RedisConnectionFactory factory) { 24 | RedisTemplate template = new RedisTemplate(); 25 | template.setConnectionFactory(factory); 26 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 27 | ObjectMapper om = new ObjectMapper(); 28 | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 29 | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 30 | jackson2JsonRedisSerializer.setObjectMapper(om); 31 | template.setKeySerializer(jackson2JsonRedisSerializer); 32 | template.setValueSerializer(jackson2JsonRedisSerializer); 33 | template.afterPropertiesSet(); 34 | return template; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/BaseService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.mvc.common.context.BaseContextHandler; 4 | import com.mvc.sell.console.dao.*; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.data.redis.core.RedisTemplate; 7 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import java.math.BigInteger; 12 | 13 | /** 14 | * base service 15 | * 16 | * @author qiyichen 17 | * @create 2018/3/12 14:46 18 | */ 19 | @Service 20 | @Transactional(rollbackFor = Exception.class) 21 | public class BaseService { 22 | 23 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(8); 24 | 25 | @Autowired 26 | AdminMapper adminMapper; 27 | @Autowired 28 | AccountMapper accountMapper; 29 | @Autowired 30 | ConfigMapper configMapper; 31 | @Autowired 32 | ProjectMapper projectMapper; 33 | @Autowired 34 | OrderMapper orderMapper; 35 | @Autowired 36 | TransactionMapper transactionMapper; 37 | @Autowired 38 | CapitalMapper capitalMapper; 39 | @Autowired 40 | ProjectSoldMapper tokenSoldMapper; 41 | @Autowired 42 | RedisTemplate redisTemplate; 43 | 44 | BigInteger getUserId() { 45 | return (BigInteger) BaseContextHandler.get("userId"); 46 | } 47 | 48 | String getOrderId(String type) { 49 | Long sid = redisTemplate.opsForValue().increment(type, 1); 50 | return type + String.format("%09d", sid); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/ConfigController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.mvc.common.msg.Result; 4 | import com.mvc.common.msg.ResultGenerator; 5 | import com.mvc.sell.console.common.annotation.NeedLogin; 6 | import com.mvc.sell.console.pojo.bean.Config; 7 | import io.swagger.annotations.ApiOperation; 8 | import org.springframework.web.bind.annotation.*; 9 | import springfox.documentation.annotations.ApiIgnore; 10 | 11 | import javax.validation.Valid; 12 | import java.util.List; 13 | 14 | /** 15 | * config controller 16 | * 17 | * @author qiyichen 18 | * @create 2018/3/10 16:44 19 | */ 20 | @RestController 21 | @RequestMapping("config") 22 | public class ConfigController extends BaseController { 23 | 24 | @ApiOperation("查询配置列表,需要有是否显示开关") 25 | @GetMapping 26 | @NeedLogin 27 | Result list() { 28 | return ResultGenerator.genSuccessResult(configService.list()); 29 | } 30 | 31 | @ApiOperation("新增配置(暂时不用,新建项目会新增配置)") 32 | @PostMapping 33 | @NeedLogin 34 | Result insert(@RequestBody @Valid Config config) { 35 | configService.insert(config); 36 | return ResultGenerator.genSuccessResult(); 37 | } 38 | 39 | @ApiOperation("更新项目") 40 | @PutMapping 41 | @NeedLogin 42 | Result update(@RequestBody @Valid Config config) { 43 | configService.update(config); 44 | return ResultGenerator.genSuccessResult(); 45 | } 46 | @ApiIgnore 47 | @GetMapping(value = "token") 48 | @NeedLogin 49 | Result> config() { 50 | return ResultGenerator.genSuccessResult(configService.token()); 51 | } 52 | 53 | ; 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/resources/messages.properties: -------------------------------------------------------------------------------- 1 | PWD_ERR=\u8D26\u53F7\u6216\u5BC6\u7801\u8F93\u5165\u9519\u8BEF! 2 | PWD_EMPTY=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A 3 | USERNAME_EMPTY=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A 4 | TOKEN_WRONG=token is wrong 5 | TOKEN_EMPTY=\u5E01\u79CD\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A 6 | TITLE_EMPTY=\u8BF7\u586B\u5199\u9879\u76EE\u6807\u9898\uFF01 7 | ETH_MIN=\u8D2D\u4E70\u6570\u91CF\u8FC7\u5C0F 8 | ADDRESS_ERROR=\u5730\u5740\u9519\u8BEF\u6216\u4E0D\u5B58\u5728 9 | CANNOT_DELETE=\u4E0D\u80FD\u5220\u9664 10 | CANNOT_SEND_TOKEN=\u4E0D\u80FD\u53D1\u5E01 11 | PROJECT_NOT_EXIST=\u9879\u76EE\u4E0D\u5B58\u5728 12 | CANNOT_RETIRE=\u4E0D\u80FD\u6E05\u9000 13 | CANNOT_CANCEL=\u4E0D\u80FD\u53D6\u6D88 14 | TOKEN_EXPIRE=\u4EE4\u724C\u5DF2\u8FC7\u671F,\u8BF7\u5237\u65B0 15 | TOKEN_NAME_EXIST=\u5E01\u79CD\u540D\u79F0\u5DF2\u5B58\u5728 16 | ETH_OVER=\u8D85\u51FA\u53EF\u8D2D\u4E70\u6570\u91CF 17 | STATUS_ERROR=\u72B6\u6001\u8BBE\u7F6E\u9519\u8BEF 18 | DIGIT_ERR=\u5C0F\u6570\u4F4D\u6570\u9519\u8BEF 19 | TRANSFER_PWD_ERR=\u4EA4\u6613\u5BC6\u7801\u9519\u8BEF 20 | USER_EMPTY=\u7528\u6237\u4E0D\u5B58\u5728 21 | EMAIL_NULL=\u8BF7\u8F93\u5165\u90AE\u7BB1\uFF01 22 | EMAIL_WRONG=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF\uFF01 23 | USER_EXIST=\u90AE\u7BB1\u5DF2\u6CE8\u518C\uFF01 24 | CODE_NULL=\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\uFF01 25 | PASSWORD_NULL=\u8BF7\u8F93\u5165\u767B\u5F55\u5BC6\u7801\uFF01 26 | TRANS_PASSWORD_NULL=\u8BF7\u8F93\u5165\u4EA4\u6613\u5BC6\u7801\uFF01 27 | ADDRESS_CLOSE=\u5145\u503C\u5730\u5740\u5DF2\u5173\u95ED 28 | ETH_NOT_ENOUGH=\u4F59\u989D\u4E0D\u8DB3 29 | NOT_ENOUGH=\u9650\u989D\u4E0D\u8DB3 30 | TOKEN_ERR=\u540D\u79F0\u9519\u8BEF\u6216\u4E0D\u5B58\u5728 31 | USER_PWD_ERR=\u5BC6\u7801\u9519\u8BEF 32 | TRANSFER_USER_PWD_ERR=\u4EA4\u6613\u5BC6\u7801\u9519\u8BEF 33 | VALI_CODE_ERR=\u9A8C\u8BC1\u7801\u9519\u8BEF -------------------------------------------------------------------------------- /src/main/resources/messages_zh_CN.properties: -------------------------------------------------------------------------------- 1 | PWD_ERR=\u8D26\u53F7\u6216\u5BC6\u7801\u8F93\u5165\u9519\u8BEF! 2 | PWD_EMPTY=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A 3 | USERNAME_EMPTY=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A 4 | TOKEN_WRONG=token is wrong 5 | TOKEN_EMPTY=\u5E01\u79CD\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A 6 | TITLE_EMPTY=\u8BF7\u586B\u5199\u9879\u76EE\u6807\u9898\uFF01 7 | ETH_MIN=\u8D2D\u4E70\u6570\u91CF\u8FC7\u5C0F 8 | ADDRESS_ERROR=\u5730\u5740\u9519\u8BEF\u6216\u4E0D\u5B58\u5728 9 | CANNOT_DELETE=\u4E0D\u80FD\u5220\u9664 10 | CANNOT_SEND_TOKEN=\u4E0D\u80FD\u53D1\u5E01 11 | PROJECT_NOT_EXIST=\u9879\u76EE\u4E0D\u5B58\u5728 12 | CANNOT_RETIRE=\u4E0D\u80FD\u6E05\u9000 13 | CANNOT_CANCEL=\u4E0D\u80FD\u53D6\u6D88 14 | TOKEN_EXPIRE=\u4EE4\u724C\u5DF2\u8FC7\u671F,\u8BF7\u5237\u65B0 15 | TOKEN_NAME_EXIST=\u5E01\u79CD\u540D\u79F0\u5DF2\u5B58\u5728 16 | ETH_OVER=\u8D85\u51FA\u53EF\u8D2D\u4E70\u6570\u91CF 17 | STATUS_ERROR=\u72B6\u6001\u8BBE\u7F6E\u9519\u8BEF 18 | DIGIT_ERR=\u5C0F\u6570\u4F4D\u6570\u9519\u8BEF 19 | TRANSFER_PWD_ERR=\u4EA4\u6613\u5BC6\u7801\u9519\u8BEF 20 | USER_EMPTY=\u7528\u6237\u4E0D\u5B58\u5728 21 | EMAIL_NULL=\u8BF7\u8F93\u5165\u90AE\u7BB1\uFF01 22 | EMAIL_WRONG=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF\uFF01 23 | USER_EXIST=\u90AE\u7BB1\u5DF2\u6CE8\u518C\uFF01 24 | CODE_NULL=\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\uFF01 25 | PASSWORD_NULL=\u8BF7\u8F93\u5165\u767B\u5F55\u5BC6\u7801\uFF01 26 | TRANS_PASSWORD_NULL=\u8BF7\u8F93\u5165\u4EA4\u6613\u5BC6\u7801\uFF01 27 | ADDRESS_CLOSE=\u5145\u503C\u5730\u5740\u5DF2\u5173\u95ED 28 | ETH_NOT_ENOUGH=\u4F59\u989D\u4E0D\u8DB3 29 | NOT_ENOUGH=\u9650\u989D\u4E0D\u8DB3 30 | TOKEN_ERR=\u540D\u79F0\u9519\u8BEF\u6216\u4E0D\u5B58\u5728 31 | USER_PWD_ERR=\u5BC6\u7801\u9519\u8BEF 32 | TRANSFER_USER_PWD_ERR=\u4EA4\u6613\u5BC6\u7801\u9519\u8BEF 33 | VALI_CODE_ERR=\u9A8C\u8BC1\u7801\u9519\u8BEF -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import com.mvc.common.exception.auth.TokenErrorException; 4 | import com.mvc.common.msg.Result; 5 | import com.mvc.common.msg.ResultGenerator; 6 | import com.mvc.sell.console.constants.MessageConstants; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.http.HttpStatus; 10 | import org.springframework.web.bind.annotation.ControllerAdvice; 11 | import org.springframework.web.bind.annotation.ExceptionHandler; 12 | import org.springframework.web.bind.annotation.ResponseBody; 13 | import org.springframework.web.bind.annotation.ResponseStatus; 14 | 15 | import javax.security.auth.login.LoginException; 16 | 17 | /** 18 | * @author qyc 19 | */ 20 | @ControllerAdvice 21 | @ResponseBody 22 | public class GlobalExceptionHandler { 23 | 24 | private Logger logger = LoggerFactory.getLogger(com.mvc.common.handler.GlobalExceptionHandler.class); 25 | 26 | @ExceptionHandler(LoginException.class) 27 | @ResponseStatus(HttpStatus.FORBIDDEN) 28 | public Result loginExceptionException() { 29 | return ResultGenerator.genFailResult(MessageConstants.TOKEN_ERROR_CODE, MessageConstants.getMsg("TOKEN_EXPIRE")); 30 | } 31 | 32 | @ExceptionHandler(TokenErrorException.class) 33 | @ResponseStatus(HttpStatus.FORBIDDEN) 34 | public Result tokenErrorExceptionException() { 35 | return ResultGenerator.genFailResult(MessageConstants.TOKEN_EXPIRE_CODE, MessageConstants.getMsg("TOKEN_EXPIRE")); 36 | } 37 | 38 | @ExceptionHandler(IllegalAccessException.class) 39 | @ResponseStatus(HttpStatus.BAD_REQUEST) 40 | public Result illegalAccessExceptionException(IllegalAccessException e) { 41 | return ResultGenerator.genFailResult(e.getMessage()); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/AdminService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.mvc.common.context.BaseContextHandler; 4 | import com.mvc.sell.console.constants.CommonConstants; 5 | import com.mvc.sell.console.constants.MessageConstants; 6 | import com.mvc.sell.console.constants.RedisConstants; 7 | import com.mvc.sell.console.pojo.bean.Admin; 8 | import com.mvc.sell.console.pojo.dto.AdminDTO; 9 | import com.mvc.sell.console.pojo.vo.TokenVO; 10 | import com.mvc.sell.console.util.JwtHelper; 11 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 12 | import org.springframework.stereotype.Service; 13 | import org.springframework.util.Assert; 14 | 15 | import java.math.BigInteger; 16 | 17 | /** 18 | * admin service 19 | * 20 | * @author qiyichen 21 | * @create 2018/3/12 14:45 22 | */ 23 | @Service 24 | public class AdminService extends BaseService { 25 | 26 | public TokenVO login(AdminDTO adminDTO) { 27 | String username = adminDTO.getUsername(); 28 | Admin admin = new Admin(); 29 | admin.setUsername(username); 30 | admin = adminMapper.selectOne(admin); 31 | Assert.notNull(admin, MessageConstants.getMsg("PWD_ERR")); 32 | boolean result = encoder.matches(adminDTO.getPassword(), admin.getPassword()); 33 | Assert.isTrue(result, MessageConstants.getMsg("PWD_ERR")); 34 | Assert.isTrue(!CommonConstants.USER_FREEZE.equals(admin.getStatus()), "用户已冻结!"); 35 | redisTemplate.opsForValue().set(RedisConstants.USER_STATUS, admin.getStatus()); 36 | String token = JwtHelper.createToken(username, admin.getId()); 37 | String refreshToken = JwtHelper.createRefresh(username, admin.getId()); 38 | return new TokenVO(token, refreshToken); 39 | } 40 | 41 | public String refresh() { 42 | BigInteger userId = (BigInteger) BaseContextHandler.get("userId"); 43 | String username = (String) BaseContextHandler.get("username"); 44 | return JwtHelper.createToken(username, userId); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/OrderService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.sell.console.constants.MessageConstants; 5 | import com.mvc.sell.console.pojo.bean.Orders; 6 | import com.mvc.sell.console.pojo.dto.OrderDTO; 7 | import com.mvc.sell.console.pojo.vo.OrderVO; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.util.Assert; 11 | 12 | import java.math.BigInteger; 13 | import java.util.List; 14 | 15 | /** 16 | * OrderService 17 | * 18 | * @author qiyichen 19 | * @create 2018/3/13 11:57 20 | */ 21 | @Service 22 | public class OrderService extends BaseService { 23 | 24 | @Autowired 25 | ConfigService configService; 26 | 27 | public void update(Orders orders) { 28 | orderMapper.updateByPrimaryKeySelective(orders); 29 | } 30 | 31 | public PageInfo list(OrderDTO orderDTO) { 32 | List list = orderMapper.listByProject(orderDTO); 33 | return new PageInfo(list); 34 | } 35 | 36 | public void updateStatus(BigInteger orderId, Integer orderStatus) { 37 | Orders orders = new Orders(); 38 | orders.setId(orderId); 39 | orders = orderMapper.selectByPrimaryKey(orderId); 40 | Assert.isTrue(orders.getOrderStatus() == 0, MessageConstants.getMsg("CANNOT_CANCEL")); 41 | orders.setOrderStatus(orderStatus); 42 | orderMapper.updateByPrimaryKeySelective(orders); 43 | tokenSoldMapper.updateEth(orders.getProjectId(), orders.getEthNumber()); 44 | capitalMapper.updateBalance(orders.getUserId(), BigInteger.ZERO, orders.getEthNumber()); 45 | 46 | } 47 | 48 | public void updateStatusByProject(BigInteger id, Integer orderStatusRetire) { 49 | orderMapper.updateStatusByProject(id, orderStatusRetire); 50 | } 51 | 52 | public void retireToken(BigInteger id, Integer orderStatusRetire) { 53 | orderMapper.retireToken(id, orderStatusRetire); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/LocaleConfig.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import java.util.Locale; 4 | 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.ComponentScan; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.support.ResourceBundleMessageSource; 10 | import org.springframework.validation.Validator; 11 | import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; 12 | import org.springframework.web.servlet.LocaleResolver; 13 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 14 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 15 | import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; 16 | import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; 17 | import org.springframework.web.servlet.i18n.SessionLocaleResolver; 18 | 19 | @Configuration 20 | @EnableAutoConfiguration 21 | @ComponentScan 22 | public class LocaleConfig extends WebMvcConfigurerAdapter { 23 | 24 | @Bean 25 | public LocaleResolver localeResolver() { 26 | AcceptHeaderLocaleResolver slr = new AcceptHeaderLocaleResolver(); 27 | // 默认语言 28 | slr.setDefaultLocale(Locale.US); 29 | return slr; 30 | } 31 | 32 | @Bean 33 | public LocaleChangeInterceptor localeChangeInterceptor() { 34 | LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); 35 | // 参数名 36 | return lci; 37 | } 38 | 39 | @Override 40 | public void addInterceptors(InterceptorRegistry registry) { 41 | registry.addInterceptor(localeChangeInterceptor()); 42 | } 43 | 44 | @Override 45 | @Bean 46 | public Validator getValidator() { 47 | ResourceBundleMessageSource rbms = new ResourceBundleMessageSource(); 48 | rbms.setDefaultEncoding("UTF-8"); 49 | rbms.setBasenames("messages"); 50 | LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean(); 51 | validator.setValidationMessageSource(rbms); 52 | return validator; 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/AdminController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.mvc.common.msg.Result; 4 | import com.mvc.common.msg.ResultGenerator; 5 | import com.mvc.sell.console.pojo.dto.AdminDTO; 6 | import com.mvc.sell.console.util.VerifyUtil; 7 | import io.swagger.annotations.ApiOperation; 8 | import org.springframework.web.bind.annotation.*; 9 | 10 | import javax.imageio.ImageIO; 11 | import javax.servlet.http.HttpServletResponse; 12 | import javax.servlet.http.HttpSession; 13 | import javax.validation.Valid; 14 | import java.awt.image.BufferedImage; 15 | import java.io.OutputStream; 16 | import java.util.concurrent.TimeUnit; 17 | 18 | /** 19 | * admin controller 20 | * 21 | * @author qiyichen 22 | * @create 2018/3/10 17:30 23 | */ 24 | @RestController 25 | @RequestMapping("admin") 26 | public class AdminController extends BaseController { 27 | 28 | /** 29 | * admin login, user check annotation 30 | * 31 | * @param adminDTO 32 | * @return 33 | */ 34 | @ApiOperation("管理员登录") 35 | @PostMapping 36 | Result login(@RequestBody @Valid AdminDTO adminDTO, HttpSession session) throws IllegalAccessException { 37 | check(session.getId(), "image", adminDTO.getImageCode()); 38 | return ResultGenerator.genSuccessResult(adminService.login(adminDTO)); 39 | } 40 | 41 | @PostMapping("token/refresh") 42 | @ApiOperation("刷新令牌") 43 | Result refresh() { 44 | return ResultGenerator.genSuccessResult(adminService.refresh()); 45 | } 46 | 47 | @ApiOperation("获取图片验证码, 注意session, 不同服务session注意分离") 48 | @GetMapping(value = "/validate/image", produces = "image/png") 49 | public void codeImage(HttpServletResponse response, HttpSession session) throws Exception { 50 | Object[] objs = VerifyUtil.createImage(); 51 | //将图片输出给浏览器 52 | BufferedImage image = (BufferedImage) objs[1]; 53 | response.setContentType("image/png"); 54 | OutputStream os = response.getOutputStream(); 55 | ImageIO.write(image, "png", os); 56 | String key = "imageCheck" + session.getId(); 57 | redisTemplate.opsForValue().set(key, objs[0]); 58 | redisTemplate.expire(key, 2, TimeUnit.MINUTES); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/OrderMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Orders; 4 | import com.mvc.sell.console.pojo.dto.OrderDTO; 5 | import com.mvc.sell.console.pojo.vo.OrderVO; 6 | import org.apache.ibatis.annotations.Param; 7 | import org.apache.ibatis.annotations.Select; 8 | import org.apache.ibatis.annotations.Update; 9 | import tk.mybatis.mapper.common.Mapper; 10 | 11 | import java.math.BigInteger; 12 | import java.util.List; 13 | 14 | /** 15 | * OrderMapper 16 | * 17 | * @author qiyichen 18 | * @create 2018/3/13 11:57 19 | */ 20 | public interface OrderMapper extends Mapper { 21 | 22 | @Select("SELECT project_id FROM orders WHERE user_id = #{userId} GROUP BY project_id") 23 | List getUserProject(BigInteger userId); 24 | 25 | @Update("update orders set order_status = #{orderStatus} where project_id = #{projectId} and order_status = 0") 26 | void updateStatusByProject(@Param("projectId") BigInteger projectId, @Param("orderStatus") Integer orderStatus); 27 | 28 | @Update("update orders set order_status = #{orderStatus} where project_id = #{projectId} and order_status in(0,2)") 29 | void retireToken(@Param("projectId") BigInteger projectId, @Param("orderStatus") Integer orderStatus); 30 | 31 | @Select({""}) 52 | List listByProject(OrderDTO orderDTO); 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/AdminControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.mvc.sell.console.pojo.dto.AdminDTO; 4 | import org.junit.Test; 5 | 6 | import static org.hamcrest.Matchers.notNullValue; 7 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 8 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 9 | 10 | public class AdminControllerTest extends BaseTest { 11 | @Test 12 | public void login() throws Exception { 13 | String path = "/admin"; 14 | AdminDTO adminDTO = new AdminDTO(); 15 | adminDTO.setUsername("mvc-admin"); 16 | adminDTO.setPassword(""); 17 | // iamgeCode error 18 | mockResult = postResult(path, adminDTO); 19 | mockResult.andExpect(status().is(400)); 20 | // password error 21 | path = "/admin/validate/image"; 22 | getResult(path, null); 23 | mockResult.andExpect(status().is(400)); 24 | String sessionId = mockResult.andReturn().getRequest().getSession().getId(); 25 | String imageCode = String.valueOf(redisTemplate.opsForValue().get("imageCheck" + sessionId)); 26 | adminDTO.setImageCode(imageCode); 27 | path = "/admin"; 28 | mockResult = postResult(path, adminDTO); 29 | mockResult.andExpect(status().is(400)); 30 | // success 31 | redisTemplate.delete("imageCheck" + sessionId); 32 | redisTemplate.opsForValue().set("imageCheck" + (Integer.valueOf(sessionId) + 3), imageCode); 33 | path = "/admin"; 34 | adminDTO.setPassword("e9c295e337aac88d63b0e351dc4d501f"); 35 | adminDTO.setImageCode(imageCode); 36 | mockResult = postResult(path, adminDTO); 37 | mockResult.andExpect(status().is(200)); 38 | mockResult.andExpect(jsonPath("$.data.token", notNullValue())); 39 | mockResult.andExpect(jsonPath("$.data.refreshToken", notNullValue())); 40 | } 41 | 42 | @Test 43 | public void refresh() throws Exception { 44 | 45 | 46 | } 47 | 48 | @Test 49 | public void codeImage() throws Exception { 50 | String path = "/admin/validate/image"; 51 | mockResult = getResult(path, null); 52 | String sessionId = mockResult.andReturn().getRequest().getSession().getId(); 53 | mockResult.andExpect(status().is(200)); 54 | } 55 | 56 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/AccountController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.common.msg.Result; 5 | import com.mvc.common.msg.ResultGenerator; 6 | import com.mvc.sell.console.common.annotation.NeedLogin; 7 | import com.mvc.sell.console.pojo.bean.Account; 8 | import com.mvc.sell.console.pojo.dto.UserFindDTO; 9 | import com.mvc.sell.console.pojo.vo.AccountVO; 10 | import com.mvc.sell.console.pojo.vo.CapitalVO; 11 | import io.swagger.annotations.ApiOperation; 12 | import org.springframework.web.bind.annotation.*; 13 | import springfox.documentation.annotations.ApiIgnore; 14 | 15 | import javax.validation.Valid; 16 | import java.math.BigInteger; 17 | import java.util.List; 18 | 19 | /** 20 | * account controller 21 | * 22 | * @author qiyichen 23 | * @create 2018/3/10 17:17 24 | */ 25 | @RestController 26 | @RequestMapping("account") 27 | public class AccountController extends BaseController { 28 | 29 | @ApiOperation("查询用户列表") 30 | @GetMapping 31 | @NeedLogin 32 | Result> list(@ModelAttribute @Valid UserFindDTO userFindDTO) { 33 | return ResultGenerator.genSuccessResult(accountService.list(userFindDTO)); 34 | } 35 | 36 | @ApiOperation("查询用户余额信息") 37 | @GetMapping("{id}/balance") 38 | @NeedLogin 39 | Result> balance(@PathVariable BigInteger id) { 40 | return ResultGenerator.genSuccessResult(accountService.balance(id)); 41 | } 42 | 43 | @ApiIgnore 44 | @GetMapping("{id}") 45 | @NeedLogin 46 | Result get(@PathVariable BigInteger id) { 47 | return ResultGenerator.genSuccessResult(accountService.get(id)); 48 | } 49 | 50 | @ApiIgnore 51 | @GetMapping("username") 52 | @NeedLogin 53 | Result get(@RequestParam String username) { 54 | return ResultGenerator.genSuccessResult(accountService.getByUserName(username)); 55 | } 56 | 57 | @ApiIgnore 58 | @PostMapping 59 | @NeedLogin 60 | Result create(@RequestBody Account account) { 61 | accountService.create(account); 62 | return ResultGenerator.genSuccessResult(); 63 | } 64 | 65 | @ApiIgnore 66 | @PutMapping 67 | @NeedLogin 68 | Result update(@RequestBody Account account) { 69 | accountService.update(account); 70 | return ResultGenerator.genSuccessResult(); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/OssService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.aliyun.oss.OSSClient; 4 | import com.aliyun.oss.common.utils.BinaryUtil; 5 | import com.aliyun.oss.model.MatchMode; 6 | import com.aliyun.oss.model.PolicyConditions; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.io.UnsupportedEncodingException; 12 | import java.util.Date; 13 | import java.util.LinkedHashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * oss service 18 | * 19 | * @author qiyichen 20 | * @create 2018/3/16 10:24 21 | */ 22 | @Service 23 | public class OssService { 24 | 25 | @Autowired 26 | OSSClient ossClient; 27 | @Value("${oss.endpoint}") 28 | private String endpoint; 29 | @Value("${oss.accessKeyId}") 30 | private String accessKeyId; 31 | @Value("${oss.accessKeySecret}") 32 | private String accessKeySecret; 33 | @Value("${oss.bucketName}") 34 | private String bucketName; 35 | 36 | public Map doGetSignature(String dir) throws UnsupportedEncodingException { 37 | String host = "http://" + bucketName + "." + endpoint; 38 | long expireTime = 300; 39 | long expireEndTime = System.currentTimeMillis() + expireTime * 1000; 40 | Date expiration = new Date(expireEndTime); 41 | PolicyConditions policyConds = new PolicyConditions(); 42 | policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); 43 | policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); 44 | String postPolicy = ossClient.generatePostPolicy(expiration, policyConds); 45 | byte[] binaryData = postPolicy.getBytes("utf-8"); 46 | String encodedPolicy = BinaryUtil.toBase64String(binaryData); 47 | String postSignature = ossClient.calculatePostSignature(postPolicy); 48 | Map responseMap = new LinkedHashMap(); 49 | responseMap.put("accessid", accessKeyId); 50 | responseMap.put("policy", encodedPolicy); 51 | responseMap.put("signature", postSignature); 52 | responseMap.put("dir", dir); 53 | responseMap.put("host", host); 54 | responseMap.put("expire", String.valueOf(expireEndTime / 1000)); 55 | return responseMap; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/util/Web3jUtil.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.util; 2 | 3 | import com.mvc.sell.console.constants.RedisConstants; 4 | import org.springframework.data.redis.core.RedisTemplate; 5 | import org.web3j.protocol.core.methods.response.Transaction; 6 | 7 | import java.math.BigDecimal; 8 | import java.math.BigInteger; 9 | 10 | /** 11 | * @author qiyichen 12 | * @create 2018/3/17 15:21 13 | */ 14 | public class Web3jUtil { 15 | 16 | private final static String ETH_FLAG = "0x"; 17 | 18 | public static String getTo(Transaction tx) { 19 | try { 20 | String to = tx.getTo(); 21 | // not transfer 22 | if (null == to) { 23 | return to; 24 | } 25 | // eth transfer 26 | if (ETH_FLAG.equalsIgnoreCase(tx.getInput())) { 27 | return to; 28 | } 29 | // token transfer 30 | if (isContractTx(tx)) { 31 | return "0x" + tx.getInput().substring(34, 74); 32 | } 33 | return null; 34 | } catch (Exception e) { 35 | return null; 36 | } 37 | } 38 | 39 | public static Boolean isContractTx(Transaction tx) { 40 | return tx.getInput().startsWith("0x64906198") || tx.getInput().startsWith("0xa9059cbb"); 41 | } 42 | 43 | public static BigDecimal getValue(BigInteger value, BigInteger tokenId, RedisTemplate redisTemplate) { 44 | if (null == tokenId) { 45 | return null; 46 | } 47 | if (tokenId.equals(BigInteger.ZERO)) { 48 | return Convert.fromWei(new BigDecimal(value), Convert.Unit.ETHER); 49 | } 50 | String name = redisTemplate.opsForValue().get(RedisConstants.UNIT + "#" + tokenId).toString(); 51 | Convert.Unit unit = Convert.Unit.valueOf(name); 52 | return Convert.fromWei(new BigDecimal(value), unit); 53 | } 54 | 55 | public static BigInteger getWei(BigDecimal realNumber, BigInteger tokenId, RedisTemplate redisTemplate) { 56 | if (null == tokenId || BigInteger.ZERO.equals(tokenId)) { 57 | return Convert.toWei(realNumber, Convert.Unit.ETHER).toBigInteger(); 58 | } else { 59 | String name = redisTemplate.opsForValue().get(RedisConstants.UNIT + "#" + tokenId).toString(); 60 | Convert.Unit unit = Convert.Unit.valueOf(name); 61 | return Convert.toWei(realNumber, unit).toBigInteger(); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/AccountService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.sell.console.pojo.bean.Account; 5 | import com.mvc.sell.console.pojo.bean.Capital; 6 | import com.mvc.sell.console.pojo.dto.UserFindDTO; 7 | import com.mvc.sell.console.pojo.vo.AccountVO; 8 | import com.mvc.sell.console.pojo.vo.CapitalVO; 9 | import com.mvc.sell.console.util.BeanUtil; 10 | import org.springframework.stereotype.Service; 11 | 12 | import java.math.BigInteger; 13 | import java.util.List; 14 | 15 | /** 16 | * AccountService 17 | * 18 | * @author qiyichen 19 | * @create 2018/3/12 20:36 20 | */ 21 | @Service 22 | public class AccountService extends BaseService { 23 | 24 | 25 | public PageInfo list(UserFindDTO userFindDTO) { 26 | Account account = new Account(); 27 | account.setUsername(userFindDTO.getUsername()); 28 | account.setId(userFindDTO.getId()); 29 | List list = accountMapper.select(account); 30 | PageInfo pageInfo = new PageInfo(list); 31 | return (PageInfo) BeanUtil.beanList2VOList(pageInfo, AccountVO.class); 32 | } 33 | 34 | public AccountVO get(BigInteger id) { 35 | Account t = new Account(); 36 | t.setId(id); 37 | Account account = accountMapper.selectByPrimaryKey(t); 38 | return (AccountVO) BeanUtil.copyProperties(account, new AccountVO()); 39 | } 40 | 41 | public AccountVO getByUserName(String username) { 42 | Account t = new Account(); 43 | t.setUsername(username); 44 | Account account = accountMapper.selectOne(t); 45 | return (AccountVO) BeanUtil.copyProperties(account, new AccountVO()); 46 | } 47 | 48 | public List balance(BigInteger id) { 49 | Capital capital = new Capital(); 50 | capital.setUserId(id); 51 | return capitalMapper.selectBalance(capital); 52 | } 53 | 54 | public void create(Account account) { 55 | accountMapper.insertSelective(account); 56 | } 57 | 58 | public void update(Account account) { 59 | accountMapper.updateByPrimaryKeySelective(account); 60 | } 61 | 62 | public Account getNonAddress() { 63 | return accountMapper.getNonAddress(); 64 | } 65 | 66 | public Account getAccount(BigInteger userId) { 67 | Account t = new Account(); 68 | t.setId(userId); 69 | return accountMapper.selectByPrimaryKey(t); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/util/Convert.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.util; 2 | 3 | import java.math.BigDecimal; 4 | 5 | public final class Convert { 6 | private Convert() { 7 | } 8 | 9 | public static BigDecimal fromWei(String number, Convert.Unit unit) { 10 | return fromWei(new BigDecimal(number), unit); 11 | } 12 | 13 | public static BigDecimal fromWei(BigDecimal number, Convert.Unit unit) { 14 | return number.divide(unit.getWeiFactor()); 15 | } 16 | 17 | public static BigDecimal toWei(String number, Convert.Unit unit) { 18 | return toWei(new BigDecimal(number), unit); 19 | } 20 | 21 | public static BigDecimal toWei(BigDecimal number, Convert.Unit unit) { 22 | return number.multiply(unit.getWeiFactor()); 23 | } 24 | 25 | public static enum Unit { 26 | WEI("wei", 0), 27 | WEI1("wei1", 1), 28 | WEI2("wei2", 2), 29 | KWEI("kwei", 3), 30 | KWEI1("kwei1", 4), 31 | KWEI2("kwei2", 5), 32 | MWEI("mwei", 6), 33 | MWEI1("mwei1", 7), 34 | MWEI2("mwei2", 8), 35 | GWEI("gwei", 9), 36 | GWEI1("gwei1", 10), 37 | GWEI2("gwei2", 11), 38 | SZABO("szabo", 12), 39 | SZABO1("szabo1", 13), 40 | SZABO2("szabo2", 14), 41 | FINNEY("finney", 15), 42 | FINNEY1("finney1", 16), 43 | FINNEY2("finney2", 17), 44 | ETHER("ether", 18), 45 | ETHER1("ether1", 19), 46 | ETHER2("ether2", 20), 47 | KETHER("kether", 21), 48 | KETHER1("kether1", 22), 49 | KETHER2("kether2", 23), 50 | METHER("mether", 24), 51 | METHER1("mether1", 25), 52 | METHER2("mether2", 26), 53 | GETHER("gether", 27); 54 | 55 | private String name; 56 | private BigDecimal weiFactor; 57 | 58 | private Unit(String name, int factor) { 59 | this.name = name; 60 | this.weiFactor = BigDecimal.TEN.pow(factor); 61 | } 62 | 63 | public BigDecimal getWeiFactor() { 64 | return this.weiFactor; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return this.name; 70 | } 71 | 72 | public static Convert.Unit fromString(String name) { 73 | if (name != null) { 74 | Convert.Unit[] var1 = values(); 75 | int var2 = var1.length; 76 | 77 | for (int var3 = 0; var3 < var2; ++var3) { 78 | Convert.Unit unit = var1[var3]; 79 | if (name.equalsIgnoreCase(unit.name)) { 80 | return unit; 81 | } 82 | } 83 | } 84 | 85 | return valueOf(name); 86 | } 87 | } 88 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/util/VerifyUtil.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.util; 2 | 3 | import java.awt.*; 4 | import java.awt.image.BufferedImage; 5 | import java.util.Random; 6 | 7 | /** 8 | * @param 9 | * @author ZZC 10 | * @date 2017年11月6日 11 | * @desc 图形验证码生成 12 | */ 13 | public class VerifyUtil { 14 | private static final char[] CHARS = { 15 | '2', '3', '4', '5', '6', '7', '8', '9', 16 | 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 17 | 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 18 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 19 | 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; 20 | private static final int SIZE = 4; 21 | private static final int LINES = 5; 22 | private static final int WIDTH = 80; 23 | private static final int HEIGHT = 40; 24 | private static final int FONT_SIZE = 27; 25 | 26 | /** 27 | * 生成随机验证码及图片 28 | * Object[0]:验证码字符串; 29 | * Object[1]:验证码图片。 30 | */ 31 | public static Object[] createImage() { 32 | StringBuffer sb = new StringBuffer(); 33 | // 1.创建空白图片 34 | BufferedImage image = new BufferedImage( 35 | WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 36 | // 2.获取图片画笔 37 | Graphics graphic = image.getGraphics(); 38 | // 3.设置画笔颜色 39 | graphic.setColor(Color.LIGHT_GRAY); 40 | // 4.绘制矩形背景 41 | graphic.fillRect(0, 0, WIDTH, HEIGHT); 42 | // 5.画随机字符 43 | Random ran = new Random(); 44 | for (int i = 0; i < SIZE; i++) { 45 | // 取随机字符索引 46 | int n = ran.nextInt(CHARS.length); 47 | // 设置随机颜色 48 | graphic.setColor(getRandomColor()); 49 | // 设置字体大小 50 | graphic.setFont(new Font( 51 | null, Font.BOLD + Font.ITALIC, FONT_SIZE)); 52 | // 画字符 53 | graphic.drawString( 54 | CHARS[n] + "", i * WIDTH / SIZE * 19 / 20, HEIGHT * 2 / 3); 55 | // 记录字符 56 | sb.append(CHARS[n]); 57 | } 58 | // 6.画干扰线 59 | for (int i = 0; i < LINES; i++) { 60 | // 设置随机颜色 61 | graphic.setColor(getRandomColor()); 62 | // 随机画线 63 | graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), 64 | ran.nextInt(WIDTH), ran.nextInt(HEIGHT)); 65 | } 66 | // 7.返回验证码和图片 67 | return new Object[]{sb.toString(), image}; 68 | } 69 | 70 | /** 71 | * 随机取色 72 | */ 73 | public static Color getRandomColor() { 74 | Random ran = new Random(); 75 | Color color = new Color(ran.nextInt(256), 76 | ran.nextInt(256), ran.nextInt(256)); 77 | return color; 78 | } 79 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/WebConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import com.mvc.common.handler.GlobalExceptionHandler; 4 | import com.mvc.sell.console.common.interceptor.ServiceAuthRestInterceptor; 5 | import com.mvc.sell.console.util.JwtHelper; 6 | import feign.Request; 7 | import org.springframework.beans.factory.annotation.Value; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.context.annotation.Primary; 11 | import org.springframework.web.servlet.config.annotation.InterceptorRegistration; 12 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 13 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 14 | 15 | import java.util.ArrayList; 16 | import java.util.Collections; 17 | 18 | /** 19 | * @author qyc 20 | */ 21 | @Configuration("admimWebConfig") 22 | @Primary 23 | public class WebConfiguration extends WebMvcConfigurerAdapter { 24 | 25 | @Value("${service.name}") 26 | private String serviceName; 27 | @Value("${service.expire}") 28 | private Long expire; 29 | @Value("${service.refresh}") 30 | private Long refresh; 31 | @Value("${service.base64Secret}") 32 | private String base64Secret; 33 | 34 | @Bean 35 | GlobalExceptionHandler getGlobalExceptionHandler() { 36 | return new GlobalExceptionHandler(); 37 | } 38 | 39 | private ArrayList getExcludeCommonPathPatterns() { 40 | ArrayList list = new ArrayList<>(); 41 | String[] urls = { 42 | "/v2/api-docs", 43 | "/swagger-resources/**", 44 | "/cache/**", 45 | "/api/log/save" 46 | }; 47 | Collections.addAll(list, urls); 48 | return list; 49 | } 50 | 51 | @Bean 52 | public ServiceAuthRestInterceptor getServiceAuthRestInterceptor() { 53 | return new ServiceAuthRestInterceptor(); 54 | } 55 | 56 | @Override 57 | public void addInterceptors(InterceptorRegistry registry) { 58 | InterceptorRegistration addInterceptor = registry.addInterceptor(getServiceAuthRestInterceptor()); 59 | // 排除配置 60 | addInterceptor.excludePathPatterns("/error"); 61 | addInterceptor.excludePathPatterns("/login**"); 62 | // 拦截配置 63 | addInterceptor.addPathPatterns("/**"); 64 | } 65 | 66 | @Bean 67 | Request.Options feignOptions() { 68 | return new Request.Options(10 * 1000, 10 * 1000); 69 | } 70 | 71 | @Bean 72 | JwtHelper jwtHelper() { 73 | JwtHelper.serviceName = serviceName; 74 | JwtHelper.expire = expire; 75 | JwtHelper.refresh = refresh; 76 | JwtHelper.base64Secret = base64Secret; 77 | return new JwtHelper(); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/BeanConfig.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import com.mvc.sell.console.service.TransactionService; 4 | import okhttp3.Interceptor; 5 | import okhttp3.OkHttpClient; 6 | import okhttp3.Request; 7 | import okhttp3.Response; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.web3j.protocol.Web3j; 12 | import org.web3j.protocol.admin.Admin; 13 | import org.web3j.protocol.http.HttpService; 14 | import org.web3j.quorum.Quorum; 15 | 16 | import java.io.IOException; 17 | import java.util.concurrent.TimeUnit; 18 | 19 | /** 20 | * beanconfig 21 | * 22 | * @author qiyichen 23 | * @create 2018/3/8 19:53 24 | */ 25 | @Configuration 26 | public class BeanConfig { 27 | 28 | @Value("${service.geth}") 29 | public String WALLET_SERVICE; 30 | 31 | @Bean 32 | public OkHttpClient okHttpClient() throws IOException { 33 | OkHttpClient.Builder builder = new OkHttpClient.Builder(); 34 | builder.connectTimeout(120, TimeUnit.SECONDS) 35 | .readTimeout(120, TimeUnit.SECONDS) 36 | .writeTimeout(120, TimeUnit.SECONDS) 37 | .retryOnConnectionFailure(true) 38 | .addInterceptor(new Interceptor() { 39 | TransactionService transactionService = SpringContextUtil.getBean("transactionService"); 40 | 41 | @Override 42 | public Response intercept(Chain chain) throws IOException { 43 | Request originalRequest = chain.request(); 44 | Request requestWithUserAgent = originalRequest.newBuilder() 45 | .build(); 46 | Response result = null; 47 | try { 48 | result = chain.proceed(requestWithUserAgent); 49 | } catch (Exception e) { 50 | e.printStackTrace(); 51 | try { 52 | transactionService.startListen(); 53 | return null; 54 | } catch (InterruptedException e1) { 55 | e1.printStackTrace(); 56 | } 57 | } 58 | return result; 59 | } 60 | }); 61 | return builder.build(); 62 | } 63 | 64 | @Bean 65 | public Quorum quorum(OkHttpClient okHttpClient) { 66 | return Quorum.build(new HttpService(WALLET_SERVICE, okHttpClient, false)); 67 | } 68 | 69 | @Bean 70 | public Admin admin(OkHttpClient okHttpClient) { 71 | return Admin.build(new HttpService(WALLET_SERVICE, okHttpClient, false)); 72 | } 73 | 74 | @Bean 75 | public Web3j web3j(OkHttpClient okHttpClient) { 76 | return Web3j.build(new HttpService(WALLET_SERVICE, okHttpClient, false)); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/dao/ProjectMapper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.dao; 2 | 3 | import com.mvc.sell.console.pojo.bean.Project; 4 | import com.mvc.sell.console.pojo.bean.ProjectSold; 5 | import com.mvc.sell.console.pojo.dto.MyProjectDTO; 6 | import com.mvc.sell.console.pojo.vo.MyProjectVO; 7 | import com.mvc.sell.console.pojo.vo.ProjectInfoVO; 8 | import org.apache.ibatis.annotations.Insert; 9 | import org.apache.ibatis.annotations.Param; 10 | import org.apache.ibatis.annotations.Select; 11 | import org.apache.ibatis.annotations.Update; 12 | import tk.mybatis.mapper.common.Mapper; 13 | 14 | import java.math.BigInteger; 15 | import java.util.List; 16 | 17 | /** 18 | * project mapper 19 | * 20 | * @author qiyichen 21 | * @create 2018/3/12 14:47 22 | */ 23 | public interface ProjectMapper extends Mapper { 24 | 25 | @Select({""}) 31 | List listDetail(MyProjectDTO myProjectDTO); 32 | 33 | @Select("select * from project t1, project_sold t2 where t1.id = t2.id and t1.id = #{id} and t1.need_show = 1") 34 | MyProjectVO detail(MyProjectDTO myProjectDTO); 35 | 36 | @Select("SELECT (SELECT IFNULL(balance,0) FROM capital WHERE user_id = #{userId} and token_id = 0) eth_balance, ratio, id project_id, token_name FROM project WHERE id = #{id}") 37 | ProjectInfoVO getInfoByUser(@Param("id") BigInteger id, @Param("userId") BigInteger userId); 38 | 39 | @Update("update project set status = 1 where start_time < now() and status = 0") 40 | Integer updateStart(); 41 | 42 | @Update("update project t1, project_sold t2 set t1.status = 2 where t1.id = t2.id and t1.status = 1 and (t1.stop_time < now() or t1.eth_number <= t2.sold_eth)") 43 | Integer updateFinish(); 44 | 45 | @Update("update project_sold set buyer_num = buyer_num+#{buyerNum}, sold_eth = sold_eth + #{soldEth} where id = #{id}") 46 | void updateSoldBalance(ProjectSold projectSold); 47 | 48 | @Update("UPDATE capital SET balance = balance + (SELECT IFNULL(sum(eth_number), 0) FROM orders where user_id = capital.user_id and project_id = #{projectId} AND order_status not in (4,9)) where token_id = 0") 49 | void retireBalance(@Param("projectId") BigInteger projectId); 50 | 51 | @Update("UPDATE capital SET balance = balance - (SELECT IFNULL(sum(token_number), 0) FROM orders where user_id = capital.user_id and project_id = #{projectId} AND order_status = 2) where token_id = #{tokenId}") 52 | void retireToken(@Param("projectId") BigInteger projectId, @Param("tokenId") BigInteger tokenId); 53 | 54 | @Select("insert IGNORE INTO capital SELECT null, user_id, #{tokenId}, IFNULL(sum(token_number),0) number FROM orders WHERE order_status = 0 AND project_id = #{projectId} GROUP BY user_id ON DUPLICATE KEY UPDATE balance = balance + IFNULL((SELECT sum(token_number) number FROM orders WHERE order_status = 0 AND project_id = #{projectId}),0)") 55 | void sendToken(@Param("projectId") BigInteger projectId, @Param("tokenId") BigInteger tokenId); 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/ConfigService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.mvc.sell.console.constants.RedisConstants; 4 | import com.mvc.sell.console.pojo.bean.Config; 5 | import com.mvc.sell.console.util.Convert; 6 | import org.springframework.stereotype.Service; 7 | 8 | import java.math.BigInteger; 9 | import java.util.Arrays; 10 | import java.util.HashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | 15 | /** 16 | * ConfigService 17 | * 18 | * @author qiyichen 19 | * @create 2018/3/13 11:02 20 | */ 21 | @Service 22 | public class ConfigService extends BaseService { 23 | 24 | ConcurrentHashMap tokenMap = new ConcurrentHashMap<>(); 25 | 26 | public List list() { 27 | return configMapper.selectAll(); 28 | } 29 | 30 | public Map map() { 31 | Map map = new HashMap<>(); 32 | for (Config config : configMapper.selectAll()) { 33 | map.put(config.getTokenName(), config); 34 | } 35 | return map; 36 | } 37 | 38 | public void insert(Config config) { 39 | String tokenName = config.getTokenName(); 40 | Config configTemp = getConfigByTokenName(tokenName); 41 | if (null != configTemp) { 42 | config.setId(configTemp.getId()); 43 | return; 44 | } 45 | configMapper.insertSelective(config); 46 | setUnit(config.getId(), config.getDecimals()); 47 | } 48 | 49 | public Config getConfigByTokenName(String tokenName) { 50 | Config config = new Config(); 51 | config.setTokenName(tokenName); 52 | config = configMapper.selectOne(config); 53 | return config; 54 | } 55 | 56 | public void update(Config config) { 57 | insert(config); 58 | configMapper.updateByPrimaryKeySelective(config); 59 | setUnit(config.getId(), config.getDecimals()); 60 | } 61 | 62 | public List token() { 63 | return configMapper.token(); 64 | } 65 | 66 | public Config get(BigInteger tokenId) { 67 | if (null == tokenId) { 68 | return null; 69 | } 70 | Config config = new Config(); 71 | config.setId(tokenId); 72 | config.setRechargeStatus(1); 73 | return configMapper.selectOne(config); 74 | } 75 | 76 | public Config getByTokenId(BigInteger tokenId) { 77 | Config config = new Config(); 78 | config.setId(tokenId); 79 | return configMapper.selectByPrimaryKey(config); 80 | } 81 | 82 | private void setUnit(BigInteger id, Integer decimals) { 83 | Arrays.stream(Convert.Unit.values()).forEach(obj -> { 84 | int value = obj.getWeiFactor().toString().length() - 1; 85 | if (decimals == value) { 86 | redisTemplate.opsForValue().set(RedisConstants.UNIT + "#" + id, obj); 87 | } 88 | } 89 | ); 90 | } 91 | 92 | public BigInteger getIdByContractAddress(String contractAddress) { 93 | Config config = new Config(); 94 | config.setContractAddress(contractAddress); 95 | return configMapper.selectOne(config).getId(); 96 | } 97 | 98 | public void initUnit() { 99 | configMapper.selectAll().stream().forEach(config -> setUnit(config.getId(), config.getDecimals())); 100 | } 101 | 102 | public String getNameByTokenId(BigInteger tokenId) { 103 | if (this.tokenMap.get(tokenId) == null) { 104 | Config config = getByTokenId(tokenId); 105 | this.tokenMap.put(tokenId, config.getTokenName()); 106 | } 107 | return this.tokenMap.get(tokenId); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/util/JwtHelper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.util; 2 | 3 | import com.mvc.common.exception.auth.TokenErrorException; 4 | import com.mvc.sell.console.constants.MessageConstants; 5 | import io.jsonwebtoken.Claims; 6 | import io.jsonwebtoken.JwtBuilder; 7 | import io.jsonwebtoken.Jwts; 8 | import io.jsonwebtoken.SignatureAlgorithm; 9 | import org.apache.log4j.Logger; 10 | import org.springframework.stereotype.Component; 11 | import org.springframework.util.Assert; 12 | 13 | import javax.crypto.spec.SecretKeySpec; 14 | import javax.security.auth.login.LoginException; 15 | import javax.xml.bind.DatatypeConverter; 16 | import java.math.BigInteger; 17 | import java.security.Key; 18 | import java.util.Date; 19 | 20 | @Component 21 | public class JwtHelper { 22 | 23 | private static Logger logger = Logger.getLogger(JwtHelper.class); 24 | 25 | public static String serviceName; 26 | public static Long expire; 27 | public static Long refresh; 28 | public static String base64Secret; 29 | 30 | public static Claims parseJWT(String jsonWebToken) { 31 | try { 32 | return Jwts.parser() 33 | .setSigningKey(DatatypeConverter.parseBase64Binary(base64Secret)) 34 | .parseClaimsJws(jsonWebToken).getBody(); 35 | } catch (Exception ex) { 36 | return null; 37 | } 38 | } 39 | 40 | public static String createToken(String username, BigInteger userId) { 41 | return createJWT(username, userId, expire, "token"); 42 | } 43 | 44 | public static String createRefresh(String username, BigInteger userId) { 45 | return createJWT(username, userId, refresh, "refresh"); 46 | } 47 | 48 | private static String createJWT(String username, BigInteger userId, Long expire, String type) { 49 | SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; 50 | //生成签名密钥 51 | byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(base64Secret); 52 | Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName()); 53 | //添加构成JWT的参数 54 | JwtBuilder builder = Jwts.builder() 55 | .claim("username", username) 56 | .claim("userId", userId) 57 | .claim("service", serviceName) 58 | .claim("type", type) 59 | .signWith(signatureAlgorithm, signingKey) 60 | .setExpiration(new Date(System.currentTimeMillis() + expire)); 61 | return builder.compact(); 62 | } 63 | 64 | public static String refresh(String refreshToken) { 65 | Claims oldToken = parseJWT(refreshToken); 66 | String username = oldToken.get("username", String.class); 67 | String service = oldToken.get("service", String.class); 68 | BigInteger userId = oldToken.get("userId", BigInteger.class); 69 | String type = oldToken.get("type", String.class); 70 | Assert.isTrue(serviceName.equalsIgnoreCase(service) && "refresh".equalsIgnoreCase(type), "token is wrong"); 71 | return createRefresh(username, userId); 72 | } 73 | 74 | 75 | public static void check(Claims claim, String uri, Boolean isFeign) throws LoginException { 76 | String type = claim.get("type", String.class); 77 | String service = claim.get("service", String.class); 78 | if (!serviceName.equalsIgnoreCase(service) && !isFeign) { 79 | throw new LoginException("service is wrong"); 80 | } 81 | if (uri.indexOf("/refresh") > 0 && !"refresh".equalsIgnoreCase(type)) { 82 | throw new LoginException("token type is wrong"); 83 | } else if (uri.indexOf("/refresh") < 0 && !"token".equalsIgnoreCase(type)) { 84 | throw new TokenErrorException(MessageConstants.getMsg("TOKEN_EXPIRE"), MessageConstants.TOKEN_EXPIRE_CODE); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/util/BeanUtil.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.util; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.google.common.collect.Lists; 5 | import com.google.common.collect.Maps; 6 | import org.springframework.beans.BeanUtils; 7 | import org.springframework.cglib.beans.BeanMap; 8 | import org.springframework.util.LinkedMultiValueMap; 9 | import org.springframework.util.MultiValueMap; 10 | 11 | import java.util.Arrays; 12 | import java.util.List; 13 | import java.util.Map; 14 | import java.util.stream.Collectors; 15 | 16 | /** 17 | * bean util 18 | * 19 | * @author qiyichen 20 | * @create 2018/3/13 10:56 21 | */ 22 | public class BeanUtil { 23 | 24 | public static PageInfo beanList2VOList(PageInfo obj, Class targetClass) { 25 | List retult = obj.getList().stream().map(account1 -> { 26 | Object instance = null; 27 | try { 28 | instance = targetClass.newInstance(); 29 | BeanUtils.copyProperties(account1, instance); 30 | } catch (InstantiationException e) { 31 | e.printStackTrace(); 32 | } catch (IllegalAccessException e) { 33 | e.printStackTrace(); 34 | } 35 | return instance; 36 | }).collect(Collectors.toList()); 37 | obj.setList(retult); 38 | return obj; 39 | } 40 | 41 | public static Object copyProperties(Object source, Object target) { 42 | if (null != source && null != target) { 43 | BeanUtils.copyProperties(source, target); 44 | } 45 | return target; 46 | } 47 | 48 | public static Map beanToMap(T bean) { 49 | Map map = Maps.newHashMap(); 50 | if (bean != null) { 51 | BeanMap beanMap = BeanMap.create(bean); 52 | for (Object key : beanMap.keySet()) { 53 | map.put(key+"", beanMap.get(key)); 54 | } 55 | } 56 | return map; 57 | } 58 | 59 | public static T mapToBean(Map map,T bean) { 60 | BeanMap beanMap = BeanMap.create(bean); 61 | beanMap.putAll(map); 62 | return bean; 63 | } 64 | 65 | public static List> objectsToMaps(List objList) { 66 | List> list = Lists.newArrayList(); 67 | if (objList != null && objList.size() > 0) { 68 | Map map = null; 69 | T bean = null; 70 | for (int i = 0,size = objList.size(); i < size; i++) { 71 | bean = objList.get(i); 72 | map = beanToMap(bean); 73 | list.add(map); 74 | } 75 | } 76 | return list; 77 | } 78 | 79 | public static List mapsToObjects(List> maps,Class clazz) throws InstantiationException, IllegalAccessException { 80 | List list = Lists.newArrayList(); 81 | if (maps != null && maps.size() > 0) { 82 | Map map = null; 83 | T bean = null; 84 | for (int i = 0,size = maps.size(); i < size; i++) { 85 | map = maps.get(i); 86 | bean = clazz.newInstance(); 87 | mapToBean(map, bean); 88 | list.add(bean); 89 | } 90 | } 91 | return list; 92 | } 93 | 94 | public static MultiValueMap beanToStringMap(Object bean) { 95 | MultiValueMap map = new LinkedMultiValueMap(); 96 | if (bean != null) { 97 | BeanMap beanMap = BeanMap.create(bean); 98 | for (Object key : beanMap.keySet()) { 99 | Object value = beanMap.get(key); 100 | if (null != beanMap.get(key)) { 101 | map.put(key+"", Arrays.asList(String.valueOf(value))); 102 | } 103 | } 104 | } 105 | return map; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.mvc.common.context.BaseContextHandler; 5 | import com.mvc.sell.console.TokenSellConsoleBootstrap; 6 | import com.mvc.sell.console.util.BeanUtil; 7 | import com.mvc.sell.console.util.JwtHelper; 8 | import org.junit.Before; 9 | import org.junit.runner.RunWith; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.boot.test.context.SpringBootTest; 12 | import org.springframework.data.redis.core.RedisTemplate; 13 | import org.springframework.http.MediaType; 14 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 15 | import org.springframework.test.context.web.WebAppConfiguration; 16 | import org.springframework.test.web.servlet.MockMvc; 17 | import org.springframework.test.web.servlet.ResultActions; 18 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 19 | import org.springframework.util.MultiValueMap; 20 | import org.springframework.web.context.WebApplicationContext; 21 | 22 | import java.math.BigInteger; 23 | import java.util.LinkedHashMap; 24 | import java.util.Map; 25 | 26 | import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; 27 | 28 | /** 29 | * BaseTest 30 | * 31 | * @author qiyichen 32 | * @create 2018/3/22 11:43 33 | */ 34 | @RunWith(SpringJUnit4ClassRunner.class) 35 | @SpringBootTest(classes = TokenSellConsoleBootstrap.class) 36 | @WebAppConfiguration 37 | public class BaseTest { 38 | 39 | @Autowired 40 | RedisTemplate redisTemplate; 41 | 42 | @Autowired 43 | WebApplicationContext context; 44 | private final static String KEY = "Authorization"; 45 | protected final static Map NULL_RESULT = new LinkedHashMap(); 46 | MockMvc mockMvc; 47 | ObjectMapper mapper = new ObjectMapper(); 48 | 49 | ResultActions mockResult; 50 | 51 | @Before 52 | public void setupMockMvc() throws Exception { 53 | mockMvc = MockMvcBuilders.webAppContextSetup(context).build(); 54 | } 55 | 56 | ResultActions postResult(String uri, Object object) throws Exception { 57 | Object token = BaseContextHandler.get(KEY); 58 | ResultActions mockResult = mockMvc.perform( 59 | post(uri) 60 | .contentType(MediaType.APPLICATION_JSON_UTF8) 61 | .header(KEY, null == token ? "" : String.valueOf(token)) 62 | .sessionAttr("sessionId", "1") 63 | .content(mapper.writeValueAsString(object)) 64 | ); 65 | return mockResult; 66 | } 67 | 68 | ResultActions putResult(String uri, Object object) throws Exception { 69 | Object token = BaseContextHandler.get(KEY); 70 | ResultActions mockResult = mockMvc.perform( 71 | put(uri) 72 | .contentType(MediaType.APPLICATION_JSON_UTF8) 73 | .header(KEY, null == token ? "" : String.valueOf(token)) 74 | .sessionAttr("id", "1") 75 | .content(mapper.writeValueAsString(object)) 76 | ); 77 | return mockResult; 78 | } 79 | 80 | ResultActions getResult(String uri, Object object) throws Exception { 81 | MultiValueMap map = BeanUtil.beanToStringMap(object); 82 | Object token = BaseContextHandler.get(KEY); 83 | ResultActions mockResult = mockMvc.perform( 84 | get(uri) 85 | .contentType(MediaType.APPLICATION_JSON_UTF8) 86 | .sessionAttr("id", "1") 87 | .params(map) 88 | .header(KEY, null == token ? "" : String.valueOf(token) 89 | ) 90 | ); 91 | return mockResult; 92 | } 93 | 94 | protected void userLogin() { 95 | String token = JwtHelper.createToken("testUser", BigInteger.valueOf(10001)); 96 | BaseContextHandler.set(KEY, token); 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | import org.springframework.boot.bind.RelaxedPropertyResolver; 4 | import org.springframework.context.EnvironmentAware; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.core.env.Environment; 8 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; 10 | import springfox.documentation.builders.ApiInfoBuilder; 11 | import springfox.documentation.builders.ParameterBuilder; 12 | import springfox.documentation.builders.PathSelectors; 13 | import springfox.documentation.builders.RequestHandlerSelectors; 14 | import springfox.documentation.schema.ModelRef; 15 | import springfox.documentation.service.ApiInfo; 16 | import springfox.documentation.service.Parameter; 17 | import springfox.documentation.spi.DocumentationType; 18 | import springfox.documentation.spring.web.plugins.Docket; 19 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 20 | 21 | import java.util.ArrayList; 22 | import java.util.List; 23 | 24 | /** 25 | * swagger配置项 26 | * 27 | * @author wanghaobin 28 | * @description 29 | * @date 2017年6月20日 30 | * @since 1.7 31 | */ 32 | @Configuration 33 | @EnableSwagger2 34 | public class SwaggerConfiguration extends WebMvcConfigurerAdapter implements EnvironmentAware { 35 | private String basePackage; 36 | private String creatName; 37 | private String serviceName; 38 | private RelaxedPropertyResolver propertyResolver; 39 | private String description; 40 | 41 | /** 42 | * 这个地方要重新注入一下资源文件,不然不会注入资源的,也没有注入requestHandlerMappping,相当于xml配置的 43 | *

44 | * 45 | *

46 | * 47 | *

48 | * 49 | *

50 | * 不知道为什么,这也是spring boot的一个缺点(菜鸟觉得的) 51 | * 52 | * @param registry 53 | */ 54 | @Override 55 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 56 | registry.addResourceHandler("swagger-ui.html") 57 | .addResourceLocations("classpath:/META-INF/resources/"); 58 | registry.addResourceHandler("/webjars*") 59 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 60 | } 61 | 62 | 63 | @Bean 64 | public Docket createRestApi() { 65 | //可以添加多个header或参数 66 | ParameterBuilder aParameterBuilder = new ParameterBuilder(); 67 | aParameterBuilder 68 | .parameterType("header") 69 | .name("Authorization") 70 | .description("token") 71 | .modelRef(new ModelRef("string")) 72 | .required(false).build(); 73 | List aParameters = new ArrayList<>(); 74 | aParameters.add(aParameterBuilder.build()); 75 | 76 | return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()) 77 | .select() 78 | .apis(RequestHandlerSelectors.basePackage(this.basePackage)) 79 | .paths(PathSelectors.any() 80 | ).build().globalOperationParameters(aParameters); 81 | } 82 | 83 | private ApiInfo apiInfo() { 84 | return new ApiInfoBuilder() 85 | .title(this.serviceName + " Restful APIs") 86 | .description(this.description) 87 | .contact(this.creatName).version("1.0").build(); 88 | } 89 | 90 | @Override 91 | public void setEnvironment(Environment environment) { 92 | this.propertyResolver = new RelaxedPropertyResolver(environment, null); 93 | this.basePackage = propertyResolver.getProperty("swagger.basepackage"); 94 | this.creatName = propertyResolver.getProperty("swagger.service.developer"); 95 | this.serviceName = propertyResolver.getProperty("swagger.service.name"); 96 | this.description = propertyResolver.getProperty("swagger.service.description"); 97 | } 98 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/common/interceptor/ServiceAuthRestInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.common.interceptor; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.mvc.common.context.BaseContextHandler; 5 | import com.mvc.common.exception.auth.TokenErrorException; 6 | import com.mvc.sell.console.common.annotation.Check; 7 | import com.mvc.sell.console.common.annotation.NeedLogin; 8 | import com.mvc.sell.console.common.exception.CheckeException; 9 | import com.mvc.sell.console.constants.MessageConstants; 10 | import com.mvc.sell.console.util.JwtHelper; 11 | import io.jsonwebtoken.Claims; 12 | import org.apache.commons.lang3.StringUtils; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import org.springframework.beans.factory.annotation.Value; 16 | import org.springframework.web.method.HandlerMethod; 17 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 18 | 19 | import javax.security.auth.login.LoginException; 20 | import javax.servlet.http.HttpServletRequest; 21 | import javax.servlet.http.HttpServletResponse; 22 | import java.math.BigInteger; 23 | 24 | /** 25 | * @author qyc 26 | */ 27 | public class ServiceAuthRestInterceptor extends HandlerInterceptorAdapter { 28 | private Logger logger = LoggerFactory.getLogger(ServiceAuthRestInterceptor.class); 29 | 30 | @Value("${service.eurekaKey}") 31 | private String eurekaKey; 32 | 33 | @Override 34 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 35 | BaseContextHandler.remove(); 36 | super.afterCompletion(request, response, handler, ex); 37 | } 38 | 39 | @Override 40 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 41 | HandlerMethod handlerMethod = (HandlerMethod) handler; 42 | 43 | String token = request.getHeader("Authorization"); 44 | Claims claim = JwtHelper.parseJWT(token); 45 | NeedLogin loginAnn = handlerMethod.getMethodAnnotation(NeedLogin.class); 46 | Check checkAnn = handlerMethod.getMethodAnnotation(Check.class); 47 | checkAnnotation(claim, loginAnn, checkAnn, request.getRequestURI(), request); 48 | setUserInfo(claim); 49 | setPage(request); 50 | return super.preHandle(request, response, handler); 51 | } 52 | 53 | private void checkAnnotation(Claims claim, NeedLogin loginAnn, Check checkAnn, String uri, HttpServletRequest request) throws LoginException, CheckeException { 54 | Boolean isFeign = "feign".equalsIgnoreCase(request.getHeader("type")) && eurekaKey.equalsIgnoreCase(request.getHeader("eurekaKey")); 55 | if (null == claim && null != loginAnn && !isFeign) { 56 | if (uri.indexOf("/refresh") > 0 ){ 57 | throw new LoginException(MessageConstants.getMsg("TOKEN_WRONG")); 58 | } else { 59 | throw new TokenErrorException(MessageConstants.getMsg("TOKEN_EXPIRE"), MessageConstants.TOKEN_EXPIRE_CODE); 60 | } 61 | } 62 | if (null != claim) { 63 | JwtHelper.check(claim, uri, isFeign); 64 | } 65 | } 66 | 67 | public void setUserInfo(Claims userInfo) { 68 | if (null != userInfo) { 69 | String username = userInfo.get("username", String.class); 70 | Integer userId = userInfo.get("userId", Integer.class); 71 | BaseContextHandler.set("username", username); 72 | BaseContextHandler.set("userId", BigInteger.valueOf(userId.longValue())); 73 | } 74 | } 75 | 76 | public void setPage(HttpServletRequest request) { 77 | if ("GET".equalsIgnoreCase(request.getMethod())) { 78 | String pageNo = request.getParameter("pageNum"); 79 | String pageSize = request.getParameter("pageSize"); 80 | String orderBy = request.getParameter("orderBy"); 81 | if (StringUtils.isNotBlank(pageNo) && StringUtils.isNotBlank(pageSize)) { 82 | PageHelper.startPage(Integer.valueOf(pageNo), Integer.valueOf(pageSize)); 83 | } 84 | if (StringUtils.isNotBlank(orderBy)) { 85 | PageHelper.orderBy(orderBy); 86 | } 87 | } 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/controller/ProjectController.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.common.msg.Result; 5 | import com.mvc.common.msg.ResultGenerator; 6 | import com.mvc.sell.console.common.Page; 7 | import com.mvc.sell.console.common.annotation.NeedLogin; 8 | import com.mvc.sell.console.pojo.dto.BuyDTO; 9 | import com.mvc.sell.console.pojo.dto.MyProjectDTO; 10 | import com.mvc.sell.console.pojo.dto.ProjectDTO; 11 | import com.mvc.sell.console.pojo.dto.WithdrawDTO; 12 | import com.mvc.sell.console.pojo.vo.*; 13 | import io.swagger.annotations.ApiOperation; 14 | import org.springframework.web.bind.annotation.*; 15 | import springfox.documentation.annotations.ApiIgnore; 16 | 17 | import javax.validation.Valid; 18 | import java.io.UnsupportedEncodingException; 19 | import java.math.BigInteger; 20 | import java.util.Map; 21 | 22 | /** 23 | * project controller 24 | * 25 | * @author qiyichen 26 | * @create 2018/3/10 17:21 27 | */ 28 | @RestController 29 | @RequestMapping("project") 30 | public class ProjectController extends BaseController { 31 | 32 | @ApiOperation("查询项目列表") 33 | @GetMapping 34 | @NeedLogin 35 | Result> list(@ModelAttribute Page page) { 36 | return ResultGenerator.genSuccessResult(projectService.list()); 37 | } 38 | 39 | @ApiOperation("新增项目") 40 | @PostMapping 41 | @NeedLogin 42 | Result add(@RequestBody @Valid ProjectDTO project) { 43 | project.setId(null); 44 | projectService.insert(project); 45 | return ResultGenerator.genSuccessResult(); 46 | } 47 | 48 | @ApiOperation("修改项目") 49 | @PutMapping 50 | @NeedLogin 51 | Result update(@RequestBody @Valid ProjectDTO project) { 52 | projectService.update(project); 53 | return ResultGenerator.genSuccessResult(); 54 | } 55 | 56 | @ApiOperation("获取单项项目详情") 57 | @GetMapping("{id}") 58 | @NeedLogin 59 | Result get(@PathVariable BigInteger id) { 60 | return ResultGenerator.genSuccessResult(projectService.get(id)); 61 | } 62 | 63 | @ApiOperation("项目销售总数据") 64 | @GetMapping("{id}/sold") 65 | @NeedLogin 66 | Result sold(@PathVariable BigInteger id) { 67 | return ResultGenerator.genSuccessResult(projectService.getSold(id)); 68 | } 69 | 70 | @ApiOperation("获取oss签名") 71 | @GetMapping("signature") 72 | @NeedLogin 73 | Result doGetSignature(@RequestParam String dir) throws UnsupportedEncodingException { 74 | return ResultGenerator.genSuccessResult(ossService.doGetSignature(dir)); 75 | } 76 | 77 | @ApiOperation("修改展示状态") 78 | @PutMapping("{id}/show/{show}") 79 | @NeedLogin 80 | Result show(@PathVariable BigInteger id, @PathVariable Integer show) { 81 | projectService.updateShow(id, show); 82 | return ResultGenerator.genSuccessResult(); 83 | } 84 | 85 | @ApiOperation("发币") 86 | @PutMapping("{id}/sendToken/{sendToken}") 87 | @NeedLogin 88 | Result sendToken(@PathVariable BigInteger id, @PathVariable Integer sendToken) { 89 | projectService.sendToken(id, sendToken); 90 | return ResultGenerator.genSuccessResult(); 91 | } 92 | 93 | @ApiOperation("清退") 94 | @PutMapping("{id}/retire/{retire}") 95 | @NeedLogin 96 | Result retire(@PathVariable BigInteger id, @PathVariable Integer retire) { 97 | projectService.retire(id, retire); 98 | return ResultGenerator.genSuccessResult(); 99 | } 100 | 101 | @ApiOperation("删除") 102 | @DeleteMapping("{id}") 103 | @NeedLogin 104 | Result retire(@PathVariable BigInteger id) { 105 | projectService.delete(id); 106 | return ResultGenerator.genSuccessResult(); 107 | } 108 | 109 | @ApiIgnore 110 | @PutMapping("{id}/status/{status}") 111 | @NeedLogin 112 | Result get(@PathVariable BigInteger id, @PathVariable Integer status) { 113 | projectService.updateStatus(id, status); 114 | return ResultGenerator.genSuccessResult(); 115 | } 116 | 117 | @ApiIgnore 118 | @GetMapping("account/{id}") 119 | @NeedLogin 120 | Result getByUser(@ModelAttribute MyProjectDTO myProjectDTO) { 121 | return ResultGenerator.genSuccessResult(projectService.getByUser(myProjectDTO)); 122 | } 123 | 124 | @ApiIgnore 125 | @GetMapping("account") 126 | @NeedLogin 127 | Result> getListByUser(@ModelAttribute MyProjectDTO myProjectDTO) { 128 | return ResultGenerator.genSuccessResult(projectService.getListByUser(myProjectDTO)); 129 | } 130 | 131 | @ApiIgnore 132 | @GetMapping("info/{id}") 133 | @NeedLogin 134 | Result info(@PathVariable BigInteger id) { 135 | return ResultGenerator.genSuccessResult(projectService.info(id)); 136 | } 137 | 138 | @ApiIgnore 139 | @PostMapping("buy") 140 | @NeedLogin 141 | Result buy(@RequestBody @Valid BuyDTO buyDTO) { 142 | projectService.buy(buyDTO); 143 | return ResultGenerator.genSuccessResult(); 144 | } 145 | 146 | @ApiIgnore 147 | @GetMapping("config") 148 | @NeedLogin 149 | Result getWithdrawConfig(@RequestParam String tokenName) { 150 | return ResultGenerator.genSuccessResult(projectService.getWithdrawConfig(tokenName)); 151 | } 152 | 153 | @ApiIgnore 154 | @PostMapping("withdraw") 155 | @NeedLogin 156 | Result withdraw(@RequestBody @Valid WithdrawDTO withdrawDTO) { 157 | projectService.withdraw(withdrawDTO); 158 | return ResultGenerator.genSuccessResult(); 159 | } 160 | 161 | } 162 | -------------------------------------------------------------------------------- /src/test/java/com/mvc/sell/console/controller/AccountControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.controller; 2 | 3 | import com.mvc.sell.console.pojo.bean.Account; 4 | import com.mvc.sell.console.pojo.dto.UserFindDTO; 5 | import org.junit.Test; 6 | 7 | import java.math.BigInteger; 8 | import java.util.UUID; 9 | 10 | import static org.hamcrest.Matchers.is; 11 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; 12 | import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; 13 | 14 | public class AccountControllerTest extends BaseTest { 15 | @Test 16 | public void list() throws Exception { 17 | String path = "/account"; 18 | UserFindDTO userFindDTO = new UserFindDTO(); 19 | mockResult = getResult(path, userFindDTO); 20 | // check login 21 | mockResult.andExpect(status().is(403)); 22 | userLogin(); 23 | // check wrong param(SQL Injection Attack) 24 | userFindDTO.setOrderBy("id desc;delete * from user"); 25 | mockResult = getResult(path, userFindDTO); 26 | mockResult.andExpect(status().is(500)); 27 | // check true param and result 28 | userFindDTO.setOrderBy("id desc"); 29 | userFindDTO.setId(BigInteger.valueOf(10001L)); 30 | mockResult = getResult(path, userFindDTO); 31 | mockResult.andExpect(status().is(200)); 32 | mockResult.andExpect(jsonPath("$.data.pageSize", is(1))); 33 | mockResult.andExpect(jsonPath("$.data.list[0].id", is(10001))); 34 | } 35 | 36 | @Test 37 | public void balance() throws Exception { 38 | String path = "/account/0/balance"; 39 | mockResult = getResult(path, null); 40 | // check login 41 | mockResult.andExpect(status().is(403)); 42 | userLogin(); 43 | // check wrong param(SQL Injection Attack) 44 | path = "/account/afafaaf/balance"; 45 | mockResult = getResult(path, null); 46 | mockResult.andExpect(status().is(500)); 47 | // check true param and result 48 | path = "/account/10001/balance"; 49 | mockResult = getResult(path, null); 50 | mockResult.andExpect(status().is(200)); 51 | mockResult.andExpect(jsonPath("$.data[0].id", is(1))); 52 | } 53 | 54 | @Test 55 | public void get() throws Exception { 56 | String path = "/account/0"; 57 | mockResult = getResult(path, null); 58 | // check login 59 | mockResult.andExpect(status().is(403)); 60 | userLogin(); 61 | // check wrong param(SQL Injection Attack) 62 | path = "/account/9999"; 63 | mockResult = getResult(path, null); 64 | mockResult.andExpect(status().is(200)); 65 | mockResult.andExpect(jsonPath("$.data", is(NULL_RESULT))); 66 | // check true param and result 67 | path = "/account/10001"; 68 | mockResult = getResult(path, null); 69 | mockResult.andExpect(status().is(200)); 70 | mockResult.andExpect(jsonPath("$.data.id", is(10001))); 71 | } 72 | 73 | @Test 74 | public void get1() throws Exception { 75 | String path = "/account/username?username=111"; 76 | mockResult = getResult(path, null); 77 | // check login 78 | mockResult.andExpect(status().is(403)); 79 | userLogin(); 80 | // check wrong param(SQL Injection Attack) 81 | mockResult = getResult(path, null); 82 | mockResult.andExpect(status().is(200)); 83 | mockResult.andExpect(jsonPath("$.data", is(NULL_RESULT))); 84 | // check true param and result 85 | path = "/account/username?username=375332835@qq.com"; 86 | mockResult = getResult(path, null); 87 | mockResult.andExpect(status().is(200)); 88 | mockResult.andExpect(jsonPath("$.data.username", is("375332835@qq.com"))); 89 | } 90 | 91 | @Test 92 | public void create() throws Exception { 93 | String path = "/account"; 94 | Account account = new Account(); 95 | String username = UUID.randomUUID() + "@qq.com"; 96 | account.setUsername(username); 97 | account.setPassword("123456"); 98 | account.setPhone("1888888888888"); 99 | account.setTransactionPassword("123456"); 100 | mockResult = postResult(path, account); 101 | // check login 102 | mockResult.andExpect(status().is(403)); 103 | userLogin(); 104 | mockResult = postResult(path, account); 105 | mockResult.andExpect(status().is(200)); 106 | path = "/account/username?username=" + username; 107 | mockResult = getResult(path, null); 108 | mockResult.andExpect(status().is(200)); 109 | mockResult.andExpect(jsonPath("$.data.username", is(username))); 110 | } 111 | 112 | @Test 113 | public void update() throws Exception { 114 | String phone = UUID.randomUUID().toString().substring(0, 16); 115 | String path = "/account"; 116 | Account account = new Account(); 117 | account.setId(BigInteger.valueOf(10001)); 118 | account.setPhone(phone); 119 | mockResult = putResult(path, account); 120 | // check login 121 | mockResult.andExpect(status().is(403)); 122 | userLogin(); 123 | // user id is get from token-sell service in token, user can not change it by request 124 | mockResult = putResult(path, account); 125 | mockResult.andExpect(status().is(200)); 126 | path = "/account/10001"; 127 | mockResult = getResult(path, null); 128 | mockResult.andExpect(status().is(200)); 129 | mockResult.andExpect(jsonPath("$.data.phone", is(phone))); 130 | } 131 | 132 | } -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/util/RsaKeyHelper.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.util; 2 | 3 | import sun.misc.BASE64Decoder; 4 | import sun.misc.BASE64Encoder; 5 | 6 | import java.io.DataInputStream; 7 | import java.io.FileOutputStream; 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.security.*; 11 | import java.security.spec.PKCS8EncodedKeySpec; 12 | import java.security.spec.X509EncodedKeySpec; 13 | import java.util.HashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @author qyc 18 | */ 19 | public class RsaKeyHelper { 20 | /** 21 | * 获取公钥 22 | * 23 | * @param filename 24 | * @return 25 | * @throws Exception 26 | */ 27 | public PublicKey getPublicKey(String filename) throws Exception { 28 | InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(filename); 29 | DataInputStream dis = new DataInputStream(resourceAsStream); 30 | byte[] keyBytes = new byte[resourceAsStream.available()]; 31 | dis.readFully(keyBytes); 32 | dis.close(); 33 | X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes); 34 | KeyFactory kf = KeyFactory.getInstance("RSA"); 35 | return kf.generatePublic(spec); 36 | } 37 | 38 | /** 39 | * 获取密钥 40 | * 41 | * @param filename 42 | * @return 43 | * @throws Exception 44 | */ 45 | public PrivateKey getPrivateKey(String filename) throws Exception { 46 | InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(filename); 47 | DataInputStream dis = new DataInputStream(resourceAsStream); 48 | byte[] keyBytes = new byte[resourceAsStream.available()]; 49 | dis.readFully(keyBytes); 50 | dis.close(); 51 | PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes); 52 | KeyFactory kf = KeyFactory.getInstance("RSA"); 53 | return kf.generatePrivate(spec); 54 | } 55 | 56 | /** 57 | * 获取公钥 58 | * 59 | * @param publicKey 60 | * @return 61 | * @throws Exception 62 | */ 63 | public PublicKey getPublicKey(byte[] publicKey) throws Exception { 64 | X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKey); 65 | KeyFactory kf = KeyFactory.getInstance("RSA"); 66 | return kf.generatePublic(spec); 67 | } 68 | 69 | /** 70 | * 获取密钥 71 | * 72 | * @param privateKey 73 | * @return 74 | * @throws Exception 75 | */ 76 | public PrivateKey getPrivateKey(byte[] privateKey) throws Exception { 77 | PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKey); 78 | KeyFactory kf = KeyFactory.getInstance("RSA"); 79 | return kf.generatePrivate(spec); 80 | } 81 | 82 | /** 83 | * 生存rsa公钥和密钥 84 | * 85 | * @param publicKeyFilename 86 | * @param privateKeyFilename 87 | * @param password 88 | * @throws IOException 89 | * @throws NoSuchAlgorithmException 90 | */ 91 | public void generateKey(String publicKeyFilename, String privateKeyFilename, String password) throws IOException, NoSuchAlgorithmException { 92 | KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 93 | SecureRandom secureRandom = new SecureRandom(password.getBytes()); 94 | keyPairGenerator.initialize(1024, secureRandom); 95 | KeyPair keyPair = keyPairGenerator.genKeyPair(); 96 | byte[] publicKeyBytes = keyPair.getPublic().getEncoded(); 97 | FileOutputStream fos = new FileOutputStream(publicKeyFilename); 98 | fos.write(publicKeyBytes); 99 | fos.close(); 100 | byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); 101 | fos = new FileOutputStream(privateKeyFilename); 102 | fos.write(privateKeyBytes); 103 | fos.close(); 104 | } 105 | 106 | /** 107 | * 生存rsa公钥 108 | * 109 | * @param password 110 | * @throws IOException 111 | * @throws NoSuchAlgorithmException 112 | */ 113 | public static byte[] generatePublicKey(String password) throws IOException, NoSuchAlgorithmException { 114 | KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 115 | SecureRandom secureRandom = new SecureRandom(password.getBytes()); 116 | keyPairGenerator.initialize(1024, secureRandom); 117 | KeyPair keyPair = keyPairGenerator.genKeyPair(); 118 | return keyPair.getPublic().getEncoded(); 119 | } 120 | 121 | /** 122 | * 生存rsa公钥 123 | * 124 | * @param password 125 | * @throws IOException 126 | * @throws NoSuchAlgorithmException 127 | */ 128 | public static byte[] generatePrivateKey(String password) throws IOException, NoSuchAlgorithmException { 129 | KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 130 | SecureRandom secureRandom = new SecureRandom(password.getBytes()); 131 | keyPairGenerator.initialize(1024, secureRandom); 132 | KeyPair keyPair = keyPairGenerator.genKeyPair(); 133 | return keyPair.getPrivate().getEncoded(); 134 | } 135 | 136 | public static Map generateKey(String password) throws IOException, NoSuchAlgorithmException { 137 | KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 138 | SecureRandom secureRandom = new SecureRandom(password.getBytes()); 139 | keyPairGenerator.initialize(1024, secureRandom); 140 | KeyPair keyPair = keyPairGenerator.genKeyPair(); 141 | byte[] publicKeyBytes = keyPair.getPublic().getEncoded(); 142 | byte[] privateKeyBytes = keyPair.getPrivate().getEncoded(); 143 | Map map = new HashMap<>(Integer.SIZE); 144 | map.put("pub", publicKeyBytes); 145 | map.put("pri", privateKeyBytes); 146 | return map; 147 | } 148 | 149 | public static String toHexString(byte[] b) { 150 | return (new BASE64Encoder()).encodeBuffer(b); 151 | } 152 | 153 | public static final byte[] toBytes(String s) throws IOException { 154 | return (new BASE64Decoder()).decodeBuffer(s); 155 | } 156 | 157 | } 158 | 159 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/config/MybatisConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.config; 2 | 3 | 4 | import com.alibaba.druid.pool.DruidDataSource; 5 | import com.github.pagehelper.PageHelper; 6 | import org.apache.commons.lang3.StringUtils; 7 | import org.apache.ibatis.plugin.Interceptor; 8 | import org.apache.ibatis.session.SqlSessionFactory; 9 | import org.mybatis.spring.SqlSessionFactoryBean; 10 | import org.mybatis.spring.SqlSessionTemplate; 11 | import org.springframework.boot.bind.RelaxedPropertyResolver; 12 | import org.springframework.context.EnvironmentAware; 13 | import org.springframework.context.annotation.Bean; 14 | import org.springframework.context.annotation.Configuration; 15 | import org.springframework.core.env.Environment; 16 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 17 | import org.springframework.core.io.support.ResourcePatternResolver; 18 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 19 | import org.springframework.transaction.annotation.EnableTransactionManagement; 20 | 21 | import javax.sql.DataSource; 22 | import java.sql.SQLException; 23 | import java.util.Properties; 24 | 25 | /** 26 | * mybatis 配置数据源类 27 | * 28 | * @author qyc 29 | */ 30 | @Configuration 31 | @EnableTransactionManagement 32 | public class MybatisConfiguration implements EnvironmentAware { 33 | 34 | 35 | private RelaxedPropertyResolver propertyResolver; 36 | 37 | private String driveClassName; 38 | private String url; 39 | private String userName; 40 | private String password; 41 | private String xmlLocation; 42 | private String typeAliasesPackage; 43 | private String filters; 44 | private String maxActive; 45 | private String initialSize; 46 | private String maxWait; 47 | private String minIdle; 48 | private String timeBetweenEvictionRunsMillis; 49 | private String minEvictableIdleTimeMillis; 50 | private String validationQuery; 51 | private String testWhileIdle; 52 | private String testOnBorrow; 53 | private String testOnReturn; 54 | private String poolPreparedStatements; 55 | private String maxOpenPreparedStatements; 56 | 57 | @Bean 58 | public DataSource druidDataSource() { 59 | DruidDataSource druidDataSource = new DruidDataSource(); 60 | druidDataSource.setUrl(url); 61 | druidDataSource.setUsername(userName); 62 | druidDataSource.setPassword(password); 63 | druidDataSource.setDriverClassName(StringUtils.isNotBlank(driveClassName) ? driveClassName : "com.mysql.jdbc.Driver"); 64 | druidDataSource.setMaxActive(StringUtils.isNotBlank(maxActive) ? Integer.parseInt(maxActive) : 10); 65 | druidDataSource.setInitialSize(StringUtils.isNotBlank(initialSize) ? Integer.parseInt(initialSize) : 1); 66 | druidDataSource.setMaxWait(StringUtils.isNotBlank(maxWait) ? Integer.parseInt(maxWait) : 60000); 67 | druidDataSource.setMinIdle(StringUtils.isNotBlank(minIdle) ? Integer.parseInt(minIdle) : 3); 68 | druidDataSource.setTimeBetweenEvictionRunsMillis(StringUtils.isNotBlank(timeBetweenEvictionRunsMillis) ? 69 | Integer.parseInt(timeBetweenEvictionRunsMillis) : 60000); 70 | druidDataSource.setMinEvictableIdleTimeMillis(StringUtils.isNotBlank(minEvictableIdleTimeMillis) ? 71 | Integer.parseInt(minEvictableIdleTimeMillis) : 300000); 72 | druidDataSource.setValidationQuery(StringUtils.isNotBlank(validationQuery) ? validationQuery : "select 'x'"); 73 | druidDataSource.setTestWhileIdle(StringUtils.isNotBlank(testWhileIdle) ? Boolean.parseBoolean(testWhileIdle) : true); 74 | druidDataSource.setTestOnBorrow(StringUtils.isNotBlank(testOnBorrow) ? Boolean.parseBoolean(testOnBorrow) : false); 75 | druidDataSource.setTestOnReturn(StringUtils.isNotBlank(testOnReturn) ? Boolean.parseBoolean(testOnReturn) : false); 76 | druidDataSource.setPoolPreparedStatements(StringUtils.isNotBlank(poolPreparedStatements) ? Boolean.parseBoolean(poolPreparedStatements) : true); 77 | druidDataSource.setMaxOpenPreparedStatements(StringUtils.isNotBlank(maxOpenPreparedStatements) ? Integer.parseInt(maxOpenPreparedStatements) : 20); 78 | 79 | try { 80 | druidDataSource.setFilters(StringUtils.isNotBlank(filters) ? filters : "stat, wall"); 81 | } catch (SQLException e) { 82 | e.printStackTrace(); 83 | } 84 | return druidDataSource; 85 | } 86 | 87 | @Bean(name = "sqlSessionFactory") 88 | public SqlSessionFactory sqlSessionFactoryBean(DataSource dataSource) { 89 | SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); 90 | bean.setDataSource(dataSource); 91 | if (StringUtils.isNotBlank(typeAliasesPackage)) { 92 | bean.setTypeAliasesPackage(typeAliasesPackage); 93 | } 94 | // 配置数据库表字段与对象属性字段的映射方式(下划线=》驼峰) 95 | org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(); 96 | configuration.setMapUnderscoreToCamelCase(true); 97 | configuration.setUseGeneratedKeys(true); 98 | bean.setConfiguration(configuration); 99 | 100 | //分页插件 101 | PageHelper pageHelper = new PageHelper(); 102 | Properties properties = new Properties(); 103 | properties.setProperty("reasonable", "true"); 104 | properties.setProperty("supportMethodsArguments", "true"); 105 | properties.setProperty("returnPageInfo", "check"); 106 | properties.setProperty("params", "count=countSql"); 107 | pageHelper.setProperties(properties); 108 | //添加XML目录 109 | ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 110 | Interceptor[] plugins = new Interceptor[]{pageHelper}; 111 | bean.setPlugins(plugins); 112 | try { 113 | return bean.getObject(); 114 | } catch (Exception e) { 115 | e.printStackTrace(); 116 | throw new RuntimeException(e); 117 | } 118 | } 119 | 120 | @Bean 121 | public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) { 122 | return new SqlSessionTemplate(sqlSessionFactory); 123 | } 124 | 125 | @Override 126 | public void setEnvironment(Environment environment) { 127 | this.propertyResolver = new RelaxedPropertyResolver(environment, null); 128 | this.url = propertyResolver.getProperty("spring.datasource.url"); 129 | this.userName = propertyResolver.getProperty("spring.datasource.username"); 130 | this.password = propertyResolver.getProperty("spring.datasource.password"); 131 | this.driveClassName = propertyResolver.getProperty("spring.datasource.driver-class-name"); 132 | this.filters = propertyResolver.getProperty("spring.datasource.filters"); 133 | this.maxActive = propertyResolver.getProperty("spring.datasource.maxActive"); 134 | this.initialSize = propertyResolver.getProperty("spring.datasource.initialSize"); 135 | this.maxWait = propertyResolver.getProperty("spring.datasource.maxWait"); 136 | this.minIdle = propertyResolver.getProperty("spring.datasource.minIdle"); 137 | this.timeBetweenEvictionRunsMillis = propertyResolver.getProperty("spring.datasource.timeBetweenEvictionRunsMillis"); 138 | this.minEvictableIdleTimeMillis = propertyResolver.getProperty("spring.datasource.minEvictableIdleTimeMillis"); 139 | this.validationQuery = propertyResolver.getProperty("spring.datasource.validationQuery"); 140 | this.testWhileIdle = propertyResolver.getProperty("spring.datasource.testWhileIdle"); 141 | this.testOnBorrow = propertyResolver.getProperty("spring.datasource.testOnBorrow"); 142 | this.testOnReturn = propertyResolver.getProperty("spring.datasource.testOnReturn"); 143 | this.poolPreparedStatements = propertyResolver.getProperty("spring.datasource.poolPreparedStatements"); 144 | this.maxOpenPreparedStatements = propertyResolver.getProperty("spring.datasource.maxOpenPreparedStatements"); 145 | this.typeAliasesPackage = propertyResolver.getProperty("mybatis.typeAliasesPackage"); 146 | this.xmlLocation = propertyResolver.getProperty("mybatis.xmlLocation"); 147 | } 148 | 149 | @Bean 150 | public DataSourceTransactionManager transactionManager(DataSource dataSource) { 151 | return new DataSourceTransactionManager(dataSource); 152 | } 153 | 154 | } 155 | -------------------------------------------------------------------------------- /src/main/resources/sql/mvc_token_sell.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : test-local 5 | Source Server Version : 50505 6 | Source Host : 192.168.203.7:3306 7 | Source Database : token_bak 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50505 11 | File Encoding : 65001 12 | 13 | Date: 2018-04-03 19:11:11 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for `account` 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `account`; 22 | CREATE TABLE `account` ( 23 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 24 | `username` varchar(64) NOT NULL, 25 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 26 | `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 27 | `status` int(1) NOT NULL DEFAULT '1', 28 | `password` varchar(128) NOT NULL, 29 | `transaction_password` varchar(128) NOT NULL, 30 | `phone` varchar(32) DEFAULT NULL, 31 | `order_num` int(11) DEFAULT '0', 32 | `address_eth` varchar(64) DEFAULT NULL, 33 | PRIMARY KEY (`id`) 34 | ) ENGINE=InnoDB AUTO_INCREMENT=10000 DEFAULT CHARSET=utf8mb4; 35 | 36 | -- ---------------------------- 37 | -- Records of account 38 | -- ---------------------------- 39 | 40 | -- ---------------------------- 41 | -- Table structure for `admin` 42 | -- ---------------------------- 43 | DROP TABLE IF EXISTS `admin`; 44 | CREATE TABLE `admin` ( 45 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 46 | `username` varchar(64) NOT NULL, 47 | `password` varchar(128) NOT NULL, 48 | `status` int(1) NOT NULL DEFAULT '1', 49 | `head_image` varchar(255) DEFAULT NULL, 50 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 51 | `update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 52 | PRIMARY KEY (`id`) 53 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 54 | 55 | -- ---------------------------- 56 | -- Records of admin 57 | -- ---------------------------- 58 | INSERT INTO `admin` VALUES ('1', 'mvc-admin', '$2a$08$0y/jCDiPLDaX8S4k81hd0OOQW5UIQJTNoUc2dAICiBZvYO65wkbQi', '1', null, '2018-03-17 04:20:38', '2018-03-22 11:56:06'); 59 | 60 | -- ---------------------------- 61 | -- Table structure for `capital` 62 | -- ---------------------------- 63 | DROP TABLE IF EXISTS `capital`; 64 | CREATE TABLE `capital` ( 65 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 66 | `user_id` bigint(20) NOT NULL, 67 | `token_id` bigint(20) NOT NULL, 68 | `balance` decimal(20,5) NOT NULL DEFAULT '0.00000', 69 | PRIMARY KEY (`id`), 70 | UNIQUE KEY `index_token_id_user_id` (`user_id`,`token_id`) USING BTREE 71 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 72 | 73 | -- ---------------------------- 74 | -- Records of capital 75 | -- ---------------------------- 76 | 77 | -- ---------------------------- 78 | -- Table structure for `config` 79 | -- ---------------------------- 80 | DROP TABLE IF EXISTS `config`; 81 | CREATE TABLE `config` ( 82 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 83 | `recharge_status` int(1) NOT NULL DEFAULT '0', 84 | `withdraw_status` int(1) NOT NULL DEFAULT '0', 85 | `min` float NOT NULL DEFAULT '0', 86 | `max` float NOT NULL DEFAULT '0', 87 | `poundage` decimal(10,5) NOT NULL DEFAULT '0.00000', 88 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 89 | `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 90 | `token_name` varchar(32) NOT NULL, 91 | `need_show` int(1) NOT NULL DEFAULT '0', 92 | `contract_address` varchar(61) DEFAULT NULL, 93 | `decimals` int(2) NOT NULL DEFAULT '0', 94 | PRIMARY KEY (`id`), 95 | UNIQUE KEY `index_token_name` (`token_name`) USING BTREE 96 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 97 | 98 | -- ---------------------------- 99 | -- Records of config 100 | -- ---------------------------- 101 | INSERT INTO `config` VALUES ('0', '1', '1', '0.05', '2', '0.00000', '2018-03-17 04:21:14', '2018-04-03 11:08:47', 'ETH', '1', null, '0'); 102 | 103 | -- ---------------------------- 104 | -- Table structure for `orders` 105 | -- ---------------------------- 106 | DROP TABLE IF EXISTS `orders`; 107 | CREATE TABLE `orders` ( 108 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 109 | `order_id` varchar(64) NOT NULL, 110 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 111 | `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 112 | `user_id` bigint(20) NOT NULL, 113 | `project_id` bigint(20) NOT NULL, 114 | `eth_number` decimal(10,5) NOT NULL DEFAULT '0.00000', 115 | `token_number` decimal(10,5) NOT NULL DEFAULT '0.00000', 116 | `order_status` int(1) NOT NULL DEFAULT '0', 117 | PRIMARY KEY (`id`) 118 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 119 | 120 | -- ---------------------------- 121 | -- Records of orders 122 | -- ---------------------------- 123 | 124 | -- ---------------------------- 125 | -- Table structure for `project` 126 | -- ---------------------------- 127 | DROP TABLE IF EXISTS `project`; 128 | CREATE TABLE `project` ( 129 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 130 | `title` varchar(64) DEFAULT NULL, 131 | `token_name` varchar(32) DEFAULT NULL, 132 | `contract_address` varchar(64) DEFAULT NULL, 133 | `eth_number` decimal(10,5) DEFAULT NULL, 134 | `ratio` float DEFAULT NULL, 135 | `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 136 | `stop_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 137 | `homepage` varchar(255) DEFAULT NULL, 138 | `white_paper_address` varchar(255) DEFAULT NULL, 139 | `white_paper_name` varchar(64) DEFAULT NULL, 140 | `project_image_address` varchar(255) DEFAULT NULL, 141 | `project_image_name` varchar(64) DEFAULT NULL, 142 | `project_cover_address` varchar(255) DEFAULT NULL, 143 | `project_cover_name` varchar(64) DEFAULT NULL, 144 | `leader_image_address` varchar(255) DEFAULT NULL, 145 | `leader_image_name` varchar(64) DEFAULT NULL, 146 | `leader_name` varchar(64) DEFAULT NULL, 147 | `position` varchar(64) DEFAULT NULL, 148 | `description` varchar(512) DEFAULT NULL, 149 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 150 | `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 151 | `status` int(1) NOT NULL DEFAULT '0', 152 | `decimals` int(2) DEFAULT NULL, 153 | `need_show` int(1) NOT NULL DEFAULT '0', 154 | `send_token` int(1) NOT NULL DEFAULT '0', 155 | `retire` int(1) NOT NULL DEFAULT '0', 156 | PRIMARY KEY (`id`) 157 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 158 | 159 | -- ---------------------------- 160 | -- Records of project 161 | -- ---------------------------- 162 | 163 | -- ---------------------------- 164 | -- Table structure for `project_sold` 165 | -- ---------------------------- 166 | DROP TABLE IF EXISTS `project_sold`; 167 | CREATE TABLE `project_sold` ( 168 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 169 | `buyer_num` int(11) NOT NULL DEFAULT '0', 170 | `sold_eth` decimal(10,5) NOT NULL DEFAULT '0.00000', 171 | `send_token` decimal(10,5) NOT NULL DEFAULT '0.00000', 172 | PRIMARY KEY (`id`) 173 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 174 | 175 | -- ---------------------------- 176 | -- Records of project_sold 177 | -- ---------------------------- 178 | 179 | -- ---------------------------- 180 | -- Table structure for `transaction` 181 | -- ---------------------------- 182 | DROP TABLE IF EXISTS `transaction`; 183 | CREATE TABLE `transaction` ( 184 | `id` bigint(20) NOT NULL AUTO_INCREMENT, 185 | `user_id` bigint(20) DEFAULT NULL, 186 | `order_id` varchar(64) DEFAULT NULL, 187 | `poundage` float DEFAULT NULL, 188 | `start_at` timestamp NULL DEFAULT NULL, 189 | `finish_at` timestamp NULL DEFAULT NULL, 190 | `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 191 | `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 192 | `number` decimal(10,5) DEFAULT NULL, 193 | `real_number` decimal(10,5) DEFAULT NULL, 194 | `token_id` bigint(20) DEFAULT NULL, 195 | `from_address` varchar(64) DEFAULT NULL, 196 | `to_address` varchar(64) DEFAULT NULL, 197 | `hash` varchar(128) DEFAULT NULL, 198 | `status` int(1) DEFAULT NULL, 199 | `type` int(1) DEFAULT NULL, 200 | PRIMARY KEY (`id`) 201 | ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; 202 | 203 | -- ---------------------------- 204 | -- Records of transaction 205 | -- ---------------------------- 206 | 207 | update config set id = 0; -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.mvc 8 | token-exchange-protocol-interior 9 | 1.0-SNAPSHOT 10 | 11 | 12 | org.springframework.boot 13 | spring-boot-starter-parent 14 | 1.5.10.RELEASE 15 | 16 | 17 | 18 | 1.5.12 19 | 20 | 21 | ${basedir}/src/main/java 22 | com.mvc.user.mapper 23 | com.mvc.user.entity 24 | 25 | ${basedir}/src/main/resources 26 | mapper 27 | 28 | 3.4.0 29 | 3.4.4 30 | 1.3.1 31 | 4.1.1 32 | 33 | 34 | 35 | 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-starter-eureka 40 | 1.3.1.RELEASE 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-starter-web 45 | 46 | 47 | org.springframework.cloud 48 | spring-cloud-starter-feign 49 | 1.3.1.RELEASE 50 | 51 | 52 | 53 | 54 | org.projectlombok 55 | lombok 56 | 1.16.14 57 | 58 | 59 | 60 | 61 | com.mvc 62 | mvc-common 63 | 1.02-SNAPSHOT 64 | 65 | 66 | 67 | 68 | com.alibaba 69 | druid 70 | 1.0.11 71 | 72 | 73 | mysql 74 | mysql-connector-java 75 | 5.1.30 76 | 77 | 78 | 79 | tk.mybatis 80 | mapper 81 | 3.4.0 82 | 83 | 84 | org.springframework.boot 85 | spring-boot-starter-jdbc 86 | 87 | 88 | 89 | com.github.pagehelper 90 | pagehelper 91 | ${pagehelper.version} 92 | 93 | 94 | 95 | org.mybatis 96 | mybatis 97 | ${mybatis.version} 98 | 99 | 100 | org.mybatis 101 | mybatis-spring 102 | ${mybatis.spring.version} 103 | 104 | 105 | 106 | com.alibaba 107 | fastjson 108 | 1.2.33 109 | 110 | 111 | 112 | 113 | org.web3j 114 | core 115 | 3.2.0 116 | 117 | 118 | 119 | org.web3j 120 | quorum 121 | 0.8.0 122 | 123 | 124 | 125 | org.springframework.boot 126 | spring-boot-starter-data-redis 127 | 128 | 129 | 130 | 131 | io.jsonwebtoken 132 | jjwt 133 | 0.7.0 134 | 135 | 136 | 137 | 138 | com.alibaba 139 | fastjson 140 | 1.2.33 141 | 142 | 143 | 144 | io.springfox 145 | springfox-swagger2 146 | 2.6.1 147 | 148 | 149 | 150 | io.springfox 151 | springfox-swagger-ui 152 | 2.6.1 153 | 154 | 155 | 156 | com.aliyun.oss 157 | aliyun-sdk-oss 158 | 2.8.3 159 | 160 | 161 | 162 | 163 | org.web3j 164 | core 165 | 3.2.0 166 | 167 | 168 | 169 | org.web3j 170 | quorum 171 | 0.8.0 172 | 173 | 174 | 175 | org.springframework.boot 176 | spring-boot-starter-test 177 | test 178 | 179 | 180 | junit 181 | junit 182 | 4.12 183 | test 184 | 185 | 186 | 187 | 188 | 189 | 190 | spring-milestones 191 | Spring Milestones 192 | https://repo.spring.io/libs-milestone 193 | 194 | false 195 | 196 | 197 | 198 | oss 199 | oss 200 | https://oss.sonatype.org/content/groups/public 201 | 202 | 203 | 204 | 205 | token-sell-console 206 | 207 | 208 | org.apache.maven.plugins 209 | maven-compiler-plugin 210 | 211 | 1.8 212 | 1.8 213 | 214 | 215 | 216 | org.apache.maven.plugins 217 | maven-surefire-plugin 218 | 2.5 219 | 220 | true 221 | 222 | 223 | 224 | org.springframework.boot 225 | spring-boot-maven-plugin 226 | 227 | 228 | 229 | 230 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/ethernum/ContractService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service.ethernum; 2 | 3 | import com.mvc.sell.console.pojo.bean.Transaction; 4 | import com.mvc.sell.console.service.TransactionService; 5 | import com.mvc.sell.console.util.Web3jUtil; 6 | import lombok.Data; 7 | import lombok.Getter; 8 | import lombok.Setter; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.scheduling.annotation.Async; 11 | import org.springframework.stereotype.Service; 12 | import org.web3j.abi.FunctionEncoder; 13 | import org.web3j.abi.TypeReference; 14 | import org.web3j.abi.datatypes.*; 15 | import org.web3j.abi.datatypes.generated.Uint256; 16 | import org.web3j.abi.datatypes.generated.Uint8; 17 | import org.web3j.protocol.core.DefaultBlockParameterName; 18 | import org.web3j.protocol.core.methods.response.EthGetBalance; 19 | import org.web3j.protocol.core.methods.response.EthSendTransaction; 20 | import org.web3j.protocol.core.methods.response.TransactionReceipt; 21 | import org.web3j.protocol.exceptions.TransactionException; 22 | import org.web3j.quorum.Quorum; 23 | import org.web3j.quorum.methods.request.PrivateTransaction; 24 | import org.web3j.quorum.tx.ClientTransactionManager; 25 | import org.web3j.tx.TransactionManager; 26 | import org.web3j.utils.Numeric; 27 | 28 | import java.io.IOException; 29 | import java.math.BigInteger; 30 | import java.util.Arrays; 31 | import java.util.Collections; 32 | import java.util.List; 33 | import java.util.concurrent.ExecutionException; 34 | import java.util.function.Function; 35 | 36 | import static org.web3j.tx.Contract.GAS_LIMIT; 37 | import static org.web3j.tx.ManagedTransaction.GAS_PRICE; 38 | 39 | /** 40 | * @author qyc 41 | */ 42 | @Service 43 | public class ContractService { 44 | 45 | private final Quorum quorum; 46 | 47 | private final NodeConfiguration nodeConfiguration; 48 | 49 | @Autowired 50 | public ContractService(Quorum quorum, NodeConfiguration nodeConfiguration) { 51 | this.quorum = quorum; 52 | this.nodeConfiguration = nodeConfiguration; 53 | } 54 | 55 | public NodeConfiguration getConfig() { 56 | return nodeConfiguration; 57 | } 58 | 59 | public String deploy( 60 | List privateFor, long initialAmount, String tokenName, long decimalUnits, 61 | String tokenSymbol) throws IOException, TransactionException { 62 | TransactionManager transactionManager = new ClientTransactionManager( 63 | quorum, nodeConfiguration.getFromAddress(), privateFor); 64 | HumanStandardToken humanStandardToken = HumanStandardToken.deploy( 65 | quorum, transactionManager, GAS_PRICE, GAS_LIMIT.divide(BigInteger.valueOf(100)), BigInteger.ZERO, 66 | new Uint256(initialAmount), new Utf8String(tokenName), new Uint8(decimalUnits), 67 | new Utf8String(tokenSymbol)); 68 | return humanStandardToken.getContractAddress(); 69 | } 70 | 71 | public String name(String contractAddress) { 72 | HumanStandardToken humanStandardToken = load(contractAddress); 73 | try { 74 | return extractValue(humanStandardToken.name().get()); 75 | } catch (InterruptedException | ExecutionException e) { 76 | throw new RuntimeException(e); 77 | } catch (IOException e) { 78 | e.printStackTrace(); 79 | } 80 | return null; 81 | } 82 | 83 | public TransactionResponse approve( 84 | List privateFor, String contractAddress, String spender, long value) { 85 | HumanStandardToken humanStandardToken = load(contractAddress, privateFor); 86 | try { 87 | TransactionReceipt transactionReceipt = humanStandardToken 88 | .approve(new Address(spender), new Uint256(value)); 89 | return processApprovalEventResponse(humanStandardToken, transactionReceipt); 90 | } catch (TransactionException e) { 91 | e.printStackTrace(); 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | } 95 | return null; 96 | } 97 | 98 | public long totalSupply(String contractAddress) { 99 | HumanStandardToken humanStandardToken = load(contractAddress); 100 | try { 101 | return extractLongValue(humanStandardToken.totalSupply().get()); 102 | } catch (InterruptedException | ExecutionException e) { 103 | throw new RuntimeException(e); 104 | } catch (IOException e) { 105 | e.printStackTrace(); 106 | } 107 | return 0; 108 | } 109 | 110 | public TransactionResponse transferFrom(List privateFor, String contractAddress, String from, String to, long value) { 111 | HumanStandardToken humanStandardToken = load(contractAddress, privateFor); 112 | try { 113 | TransactionReceipt transactionReceipt = humanStandardToken 114 | .transferFrom(new Address(from), new Address(to), new Uint256(value)); 115 | 116 | System.out.println(transactionReceipt.getTransactionHash()); 117 | return processTransferEventsResponse(humanStandardToken, transactionReceipt); 118 | } catch (TransactionException e) { 119 | e.printStackTrace(); 120 | } catch (IOException e) { 121 | e.printStackTrace(); 122 | } 123 | return null; 124 | } 125 | 126 | public EthSendTransaction eth_sendTransaction(org.web3j.protocol.core.methods.request.Transaction transaction, String contractAddress) throws Exception { 127 | org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function("transfer", Arrays.asList(new Address(transaction.getTo()), new Uint256(Numeric.decodeQuantity(transaction.getValue()))), Collections.>emptyList()); 128 | String data = FunctionEncoder.encode(function); 129 | PrivateTransaction privateTransaction = new PrivateTransaction(transaction.getFrom(), null, GAS_LIMIT.divide(BigInteger.valueOf(30)), contractAddress, BigInteger.ZERO, data, Arrays.asList(transaction.getFrom(), transaction.getTo(), contractAddress)); 130 | EthSendTransaction response = quorum.ethSendTransaction(privateTransaction).send(); 131 | return response; 132 | } 133 | 134 | public long decimals(String contractAddress) { 135 | HumanStandardToken humanStandardToken = load(contractAddress); 136 | try { 137 | return extractLongValue(humanStandardToken.decimals().get()); 138 | } catch (InterruptedException | ExecutionException e) { 139 | throw new RuntimeException(e); 140 | } catch (IOException e) { 141 | e.printStackTrace(); 142 | } 143 | return 0; 144 | } 145 | 146 | public String version(String contractAddress) { 147 | HumanStandardToken humanStandardToken = load(contractAddress); 148 | try { 149 | return extractValue(humanStandardToken.version().get()); 150 | } catch (InterruptedException | ExecutionException e) { 151 | throw new RuntimeException(e); 152 | } catch (IOException e) { 153 | e.printStackTrace(); 154 | } 155 | return null; 156 | } 157 | 158 | public BigInteger balanceOf(String contractAddress, String ownerAddress) { 159 | HumanStandardToken humanStandardToken = load(contractAddress); 160 | try { 161 | Uint256 balance = humanStandardToken.balanceOf(new Address(ownerAddress)); 162 | return balance.getValue(); 163 | } catch (IOException e) { 164 | e.printStackTrace(); 165 | } 166 | return BigInteger.ZERO; 167 | } 168 | 169 | public String symbol(String contractAddress) { 170 | HumanStandardToken humanStandardToken = load(contractAddress); 171 | try { 172 | return extractValue(humanStandardToken.symbol().get()); 173 | } catch (InterruptedException | ExecutionException e) { 174 | throw new RuntimeException(e); 175 | } catch (IOException e) { 176 | e.printStackTrace(); 177 | } 178 | return null; 179 | } 180 | 181 | public TransactionResponse transfer( 182 | List privateFor, String contractAddress, String to, long value) throws IOException { 183 | HumanStandardToken humanStandardToken = load(contractAddress, privateFor); 184 | try { 185 | TransactionReceipt transactionReceipt = humanStandardToken 186 | .transfer(new Address(to), new Uint256(value)); 187 | return processTransferEventsResponse(humanStandardToken, transactionReceipt); 188 | } catch (TransactionException e) { 189 | e.printStackTrace(); 190 | } catch (IOException e) { 191 | e.printStackTrace(); 192 | } 193 | return null; 194 | } 195 | 196 | public TransactionResponse approveAndCall( 197 | List privateFor, String contractAddress, String spender, long value, 198 | String extraData) { 199 | HumanStandardToken humanStandardToken = load(contractAddress, privateFor); 200 | try { 201 | TransactionReceipt transactionReceipt = humanStandardToken 202 | .approveAndCall( 203 | new Address(spender), new Uint256(value), 204 | new DynamicBytes(extraData.getBytes())); 205 | return processApprovalEventResponse(humanStandardToken, transactionReceipt); 206 | } catch (TransactionException e) { 207 | e.printStackTrace(); 208 | } catch (IOException e) { 209 | e.printStackTrace(); 210 | } 211 | return null; 212 | } 213 | 214 | public long allowance(String contractAddress, String ownerAddress, String spenderAddress) { 215 | HumanStandardToken humanStandardToken = load(contractAddress); 216 | try { 217 | return extractLongValue((Uint) humanStandardToken.allowance( 218 | new Address(ownerAddress), new Address(spenderAddress)) 219 | ); 220 | } catch (IOException e) { 221 | e.printStackTrace(); 222 | } 223 | return 0; 224 | } 225 | 226 | private HumanStandardToken load(String contractAddress, List privateFor) { 227 | TransactionManager transactionManager = new ClientTransactionManager( 228 | quorum, nodeConfiguration.getFromAddress(), privateFor); 229 | return HumanStandardToken.load( 230 | contractAddress, quorum, transactionManager, GAS_PRICE.divide(BigInteger.valueOf(100)), GAS_LIMIT.divide(BigInteger.valueOf(100))); 231 | } 232 | 233 | private HumanStandardToken load(String contractAddress) { 234 | TransactionManager transactionManager = new ClientTransactionManager( 235 | quorum, nodeConfiguration.getFromAddress(), Collections.emptyList()); 236 | return HumanStandardToken.load( 237 | contractAddress, quorum, transactionManager, GAS_PRICE.divide(BigInteger.valueOf(100)), GAS_LIMIT.divide(BigInteger.valueOf(100))); 238 | } 239 | 240 | private T extractValue(Type value) { 241 | if (value != null) { 242 | return value.getValue(); 243 | } else { 244 | throw new RuntimeException("Empty value returned by call"); 245 | } 246 | } 247 | 248 | private long extractLongValue(Uint value) { 249 | return extractValue(value).longValueExact(); 250 | } 251 | 252 | private TransactionResponse 253 | processApprovalEventResponse( 254 | HumanStandardToken humanStandardToken, 255 | TransactionReceipt transactionReceipt) { 256 | 257 | return processEventResponse( 258 | humanStandardToken.getApprovalEvents(transactionReceipt), 259 | transactionReceipt, 260 | ApprovalEventResponse::new); 261 | } 262 | 263 | private TransactionResponse 264 | processTransferEventsResponse( 265 | HumanStandardToken humanStandardToken, 266 | TransactionReceipt transactionReceipt) { 267 | 268 | return processEventResponse( 269 | humanStandardToken.getTransferEvents(transactionReceipt), 270 | transactionReceipt, 271 | TransferEventResponse::new); 272 | } 273 | 274 | private TransactionResponse processEventResponse( 275 | List eventResponses, TransactionReceipt transactionReceipt, Function map) { 276 | if (!eventResponses.isEmpty()) { 277 | return new TransactionResponse<>( 278 | transactionReceipt.getTransactionHash(), 279 | map.apply(eventResponses.get(0))); 280 | } else { 281 | return new TransactionResponse<>( 282 | transactionReceipt.getTransactionHash()); 283 | } 284 | } 285 | 286 | @Data 287 | public static class TransferEventResponse { 288 | private String from; 289 | private String to; 290 | private long value; 291 | 292 | public TransferEventResponse() { 293 | } 294 | 295 | public TransferEventResponse( 296 | HumanStandardToken.TransferEventResponse transferEventResponse) { 297 | this.from = transferEventResponse.from.toString(); 298 | this.to = transferEventResponse.to.toString(); 299 | this.value = transferEventResponse.value.getValue().longValueExact(); 300 | } 301 | } 302 | 303 | @Getter 304 | @Setter 305 | public static class ApprovalEventResponse { 306 | private String owner; 307 | private String spender; 308 | private long value; 309 | 310 | public ApprovalEventResponse() { 311 | } 312 | 313 | public ApprovalEventResponse( 314 | HumanStandardToken.ApprovalEventResponse approvalEventResponse) { 315 | this.owner = approvalEventResponse.owner.toString(); 316 | this.spender = approvalEventResponse.spender.toString(); 317 | this.value = approvalEventResponse.value.getValue().longValueExact(); 318 | } 319 | } 320 | } 321 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/ProjectService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.common.context.BaseContextHandler; 5 | import com.mvc.sell.console.constants.CommonConstants; 6 | import com.mvc.sell.console.constants.MessageConstants; 7 | import com.mvc.sell.console.constants.RedisConstants; 8 | import com.mvc.sell.console.pojo.bean.*; 9 | import com.mvc.sell.console.pojo.dto.BuyDTO; 10 | import com.mvc.sell.console.pojo.dto.MyProjectDTO; 11 | import com.mvc.sell.console.pojo.dto.ProjectDTO; 12 | import com.mvc.sell.console.pojo.dto.WithdrawDTO; 13 | import com.mvc.sell.console.pojo.vo.*; 14 | import com.mvc.sell.console.util.BeanUtil; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.beans.factory.annotation.Value; 17 | import org.springframework.stereotype.Service; 18 | import org.springframework.util.Assert; 19 | 20 | import java.math.BigDecimal; 21 | import java.math.BigInteger; 22 | import java.util.List; 23 | import java.util.Map; 24 | 25 | /** 26 | * project service 27 | * 28 | * @author qiyichen 29 | * @author dreamingodd 30 | * @create 2018/3/13 11:25 31 | *

32 | * Added withdraw availability(status) of the token of the project symbol in the list. 33 | * @updated 2018/4/2 34 | */ 35 | @Service 36 | public class ProjectService extends BaseService { 37 | 38 | @Autowired 39 | ConfigService configService; 40 | @Autowired 41 | AccountService accountService; 42 | @Autowired 43 | OrderService orderService; 44 | @Value("${wallet.user}") 45 | String defaultUser; 46 | 47 | public PageInfo list() { 48 | List list = projectMapper.selectAll(); 49 | PageInfo page = new PageInfo<>(list); 50 | PageInfo voPage = (PageInfo) BeanUtil.beanList2VOList(page, ProjectVO.class); 51 | Map configMap = configService.map(); 52 | for (ProjectVO projectVO : voPage.getList()) { 53 | projectVO.setTokenWithdrawStatus(0); 54 | Config config = configMap.get(projectVO.getTokenName()); 55 | if (config != null) { 56 | projectVO.setTokenWithdrawStatus(config.getWithdrawStatus()); 57 | } 58 | } 59 | return voPage; 60 | } 61 | 62 | public void insert(ProjectDTO projectDTO) { 63 | Project project = (Project) BeanUtil.copyProperties(projectDTO, new Project()); 64 | projectMapper.insertSelective(project); 65 | ProjectSold projectSold = new ProjectSold(); 66 | projectSold.setId(project.getId()); 67 | projectSold.setBuyerNum(0); 68 | projectSold.setSendToken(BigDecimal.ZERO); 69 | projectSold.setSoldEth(BigDecimal.ZERO); 70 | tokenSoldMapper.insert(projectSold); 71 | } 72 | 73 | public void update(ProjectDTO projectDTO) { 74 | Project project = (Project) BeanUtil.copyProperties(projectDTO, new Project()); 75 | projectMapper.updateByPrimaryKeySelective(project); 76 | } 77 | 78 | public ProjectVO get(BigInteger id) { 79 | Project project = projectMapper.selectByPrimaryKey(id); 80 | return (ProjectVO) BeanUtil.copyProperties(project, new ProjectVO()); 81 | } 82 | 83 | public void updateStatus(BigInteger id, Integer status) { 84 | Project project = new Project(); 85 | project.setId(id); 86 | project.setStatus(status); 87 | projectMapper.updateByPrimaryKeySelective(project); 88 | } 89 | 90 | public ProjectSoldVO getSold(BigInteger id) { 91 | ProjectSold projectSold = new ProjectSold(); 92 | projectSold.setId(id); 93 | return tokenSoldMapper.selectSold(projectSold); 94 | } 95 | 96 | public MyProjectVO getByUser(MyProjectDTO myProjectDTO) { 97 | BigInteger userId = (BigInteger) BaseContextHandler.get("userId"); 98 | List userProjects = getUserProject(userId); 99 | MyProjectVO result = projectMapper.detail(myProjectDTO); 100 | if (null != userId) { 101 | result.setPartake(userProjects.contains(result.getId())); 102 | } 103 | return result; 104 | } 105 | 106 | public PageInfo getListByUser(MyProjectDTO myProjectDTO) { 107 | BigInteger userId = (BigInteger) BaseContextHandler.get("userId"); 108 | List list = projectMapper.listDetail(myProjectDTO); 109 | if (null != userId) { 110 | List userProjects = getUserProject(userId); 111 | list.stream().forEach(obj -> obj.setPartake(userProjects.contains(obj.getId()))); 112 | } 113 | return new PageInfo<>(list); 114 | } 115 | 116 | private List getUserProject(BigInteger userId) { 117 | String key = RedisConstants.USER_PROJECTS + "#" + userId; 118 | if (!redisTemplate.hasKey(key)) { 119 | redisTemplate.opsForValue().set(key, orderMapper.getUserProject(userId)); 120 | } 121 | return (List) redisTemplate.opsForValue().get(key); 122 | } 123 | 124 | 125 | public ProjectInfoVO info(BigInteger id) { 126 | return projectMapper.getInfoByUser(id, getUserId()); 127 | } 128 | 129 | public void buy(BuyDTO buyDTO) { 130 | // update order number 131 | Account account = accountService.getAccount(getUserId()); 132 | Assert.isTrue(encoder.matches(buyDTO.getTransactionPassword(), account.getTransactionPassword()), MessageConstants.getMsg("TRANSFER_PWD_ERR")); 133 | ProjectVO project = get(buyDTO.getProjectId()); 134 | Assert.notNull(project, MessageConstants.getMsg("PROJECT_NOT_EXIST")); 135 | BigDecimal sold = getSold(buyDTO.getProjectId()).getSoldEth(); 136 | Assert.isTrue(sold.add(buyDTO.getEthNumber()).compareTo(project.getEthNumber()) <= 0, MessageConstants.getMsg("ETH_OVER")); 137 | BigDecimal balance = buyDTO.getEthNumber().multiply(new BigDecimal(project.getRatio())); 138 | // update ethBalance 139 | Capital ethCapital = new Capital(); 140 | ethCapital.setUserId(getUserId()); 141 | ethCapital.setTokenId(BigInteger.ZERO); 142 | Integer result = capitalMapper.updateEth(getUserId(), buyDTO.getEthNumber()); 143 | Assert.isTrue(result > 0, MessageConstants.getMsg("ETH_NOT_ENOUGH")); 144 | // add order 145 | addOrder(buyDTO, balance); 146 | Integer orderNum = account.getOrderNum(); 147 | orderNum = null == orderNum ? 1 : ++orderNum; 148 | account.setOrderNum(orderNum); 149 | accountService.update(account); 150 | sold = getSold(buyDTO.getProjectId()).getSoldEth(); 151 | Assert.isTrue(sold.compareTo(project.getEthNumber()) <= 0, MessageConstants.getMsg("ETH_OVER")); 152 | String key = RedisConstants.USER_PROJECTS + "#" + getUserId(); 153 | redisTemplate.opsForValue().set(key, orderMapper.getUserProject(getUserId())); 154 | } 155 | 156 | private void addOrder(BuyDTO buyDTO, BigDecimal balance) { 157 | Orders orders = new Orders(); 158 | orders.setUserId(getUserId()); 159 | orders.setEthNumber(buyDTO.getEthNumber()); 160 | orders.setOrderId(getOrderId(CommonConstants.ORDER_BUY)); 161 | orders.setOrderStatus(0); 162 | orders.setProjectId(buyDTO.getProjectId()); 163 | orders.setTokenNumber(balance); 164 | orderMapper.insert(orders); 165 | updateSold(buyDTO.getProjectId(), buyDTO.getEthNumber(), balance); 166 | } 167 | 168 | private void updateSold(BigInteger projectId, BigDecimal ethNumber, BigDecimal balance) { 169 | Orders orders = new Orders(); 170 | orders.setUserId(getUserId()); 171 | orders.setProjectId(projectId); 172 | ProjectSold projectSold = new ProjectSold(); 173 | projectSold.setId(projectId); 174 | projectSold.setSoldEth(ethNumber); 175 | projectSold.setBuyerNum(1); 176 | projectMapper.updateSoldBalance(projectSold); 177 | } 178 | 179 | public WithdrawInfoVO getWithdrawConfig(String tokenName) { 180 | Config config = getConfig(tokenName); 181 | Assert.notNull(config, MessageConstants.getMsg("TOKEN_ERR")); 182 | WithdrawInfoVO withdrawInfoVO = (WithdrawInfoVO) BeanUtil.copyProperties(config, new WithdrawInfoVO()); 183 | Capital capital = new Capital(); 184 | capital.setUserId(getUserId()); 185 | capital.setTokenId(config.getId()); 186 | capital = capitalMapper.selectOne(capital); 187 | withdrawInfoVO.setBalance(null == capital ? BigDecimal.ZERO : capital.getBalance()); 188 | String key = RedisConstants.TODAY_USER + "#" + tokenName + "#" + getUserId(); 189 | BigDecimal use = (BigDecimal) redisTemplate.opsForValue().get(key); 190 | withdrawInfoVO.setTodayUse(null == use ? BigDecimal.ZERO : use); 191 | return withdrawInfoVO; 192 | } 193 | 194 | public void withdraw(WithdrawDTO withdrawDTO) { 195 | // check 196 | checkAccount(withdrawDTO); 197 | Config config = getConfig(withdrawDTO.getTokenName()); 198 | Assert.notNull(config, MessageConstants.getMsg("TOKEN_ERR")); 199 | checkCanWithdraw(withdrawDTO, config); 200 | checkEthBalance(withdrawDTO, config); 201 | // add trans 202 | Transaction transaction = new Transaction(); 203 | transaction.setStatus(0); 204 | transaction.setNumber(withdrawDTO.getNumber()); 205 | transaction.setOrderId(getOrderId(CommonConstants.ORDER_WITHDRAW)); 206 | transaction.setPoundage(config.getPoundage()); 207 | transaction.setRealNumber(withdrawDTO.getNumber().subtract(BigDecimal.valueOf(config.getPoundage()))); 208 | transaction.setToAddress(withdrawDTO.getAddress()); 209 | transaction.setType(CommonConstants.WITHDRAW); 210 | transaction.setUserId(getUserId()); 211 | transaction.setTokenId(config.getId()); 212 | transaction.setFromAddress(defaultUser); 213 | transactionMapper.insert(transaction); 214 | capitalMapper.updateBalance(getUserId(), config.getId(), BigDecimal.ZERO.subtract(withdrawDTO.getNumber())); 215 | String key = RedisConstants.TODAY_USER + "#" + withdrawDTO.getTokenName() + "#" + getUserId(); 216 | BigDecimal use = (BigDecimal) redisTemplate.opsForValue().get(key); 217 | use = use == null ? withdrawDTO.getNumber() : use.add(withdrawDTO.getNumber()); 218 | redisTemplate.opsForValue().set(key, use); 219 | } 220 | 221 | private void checkCanWithdraw(WithdrawDTO withdrawDTO, Config config) { 222 | String addressKey = RedisConstants.LISTEN_ETH_ADDR + "#" + withdrawDTO.getAddress(); 223 | // 不能提现到临时地址 224 | Assert.isTrue(!redisTemplate.hasKey(addressKey), MessageConstants.getMsg("ADDRESS_ERROR")); 225 | String key = RedisConstants.TODAY_USER + "#" + withdrawDTO.getTokenName() + "#" + getUserId(); 226 | BigDecimal use = (BigDecimal) redisTemplate.opsForValue().get(key); 227 | use = null == use ? BigDecimal.ZERO : use; 228 | Boolean canWithdraw = BigDecimal.valueOf(config.getMax()).subtract(use).compareTo(withdrawDTO.getNumber()) >= 0; 229 | Assert.isTrue(canWithdraw, MessageConstants.getMsg("NOT_ENOUGH")); 230 | } 231 | 232 | private void checkEthBalance(WithdrawDTO withdrawDTO, Config config) { 233 | Capital capital = new Capital(); 234 | capital.setTokenId(config.getId()); 235 | capital.setUserId(getUserId()); 236 | capital = capitalMapper.selectOne(capital); 237 | Assert.isTrue(null != capital && capital.getBalance().compareTo(withdrawDTO.getNumber()) > 0, MessageConstants.getMsg("ETH_NOT_ENOUGH")); 238 | } 239 | 240 | private Config getConfig(String tokenName) { 241 | Config config = new Config(); 242 | config.setTokenName(tokenName); 243 | config.setNeedShow(1); 244 | config = configMapper.selectOne(config); 245 | return config; 246 | } 247 | 248 | private void checkAccount(WithdrawDTO withdrawDTO) { 249 | AccountVO account = accountService.get(getUserId()); 250 | Assert.isTrue(encoder.matches(withdrawDTO.getTransactionPassword(), account.getTransactionPassword()), MessageConstants.getMsg("TRANSFER_USER_PWD_ERR")); 251 | } 252 | 253 | public Integer updateStatus() { 254 | Integer number = 0; 255 | number = number + projectMapper.updateStart(); 256 | number = number + projectMapper.updateFinish(); 257 | return number; 258 | } 259 | 260 | public void updateShow(BigInteger id, Integer show) { 261 | Project project = new Project(); 262 | project.setId(id); 263 | project.setNeedShow(show); 264 | projectMapper.updateByPrimaryKeySelective(project); 265 | } 266 | 267 | private Project getNotNullById(BigInteger id) { 268 | Project project = new Project(); 269 | project.setId(id); 270 | project = projectMapper.selectByPrimaryKey(project); 271 | // 项目开始前或项目发币后可用 272 | Assert.notNull(project, MessageConstants.getMsg("PROJECT_NOT_EXIST")); 273 | return project; 274 | } 275 | 276 | public void sendToken(BigInteger id, Integer sendToken) { 277 | Project project = getNotNullById(id); 278 | Config config = configService.getConfigByTokenName(project.getTokenName()); 279 | // 当前未发币且项目结束后可用 280 | Boolean canSend = project.getStatus().equals(2) && project.getSendToken() == 0; 281 | Assert.isTrue(canSend, MessageConstants.getMsg("CANNOT_SEND_TOKEN")); 282 | project.setSendToken(1); 283 | projectMapper.updateByPrimaryKeySelective(project); 284 | projectMapper.sendToken(id, config.getId()); 285 | orderService.updateStatusByProject(id, CommonConstants.ORDER_STATUS_SEND_TOKEN); 286 | } 287 | 288 | public void retire(BigInteger id, Integer retire) { 289 | Project project = getNotNullById(id); 290 | // 项目结束后可用, 使用一次此功能后或此项目代币开放提币后禁用 291 | Config config = configService.getConfigByTokenName(project.getTokenName()); 292 | Boolean canRetire = project.getStatus().equals(2) && project.getRetire().equals(0) && config.getWithdrawStatus().equals(0); 293 | Assert.isTrue(canRetire, MessageConstants.getMsg("CANNOT_RETIRE")); 294 | project.setRetire(1); 295 | projectMapper.updateByPrimaryKeySelective(project); 296 | Orders orders = new Orders(); 297 | orders.setProjectId(id); 298 | if (orderMapper.selectCount(orders) > 0) { 299 | projectMapper.retireBalance(id); 300 | projectMapper.retireToken(id, config.getId()); 301 | orderService.retireToken(id, CommonConstants.ORDER_STATUS_RETIRE); 302 | } 303 | } 304 | 305 | public List select(Project project) { 306 | return projectMapper.select(project); 307 | } 308 | 309 | public void delete(BigInteger id) { 310 | Project project = getNotNullById(id); 311 | Boolean canDelete = project.getStatus().equals(0) || project.getSendToken().equals(1); 312 | Assert.isTrue(canDelete, MessageConstants.getMsg("CANNOT_DELETE")); 313 | projectMapper.delete(project); 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /src/main/java/com/mvc/sell/console/service/TransactionService.java: -------------------------------------------------------------------------------- 1 | package com.mvc.sell.console.service; 2 | 3 | import com.github.pagehelper.PageInfo; 4 | import com.mvc.sell.console.constants.CommonConstants; 5 | import com.mvc.sell.console.constants.MessageConstants; 6 | import com.mvc.sell.console.constants.RedisConstants; 7 | import com.mvc.sell.console.pojo.bean.Account; 8 | import com.mvc.sell.console.pojo.bean.Capital; 9 | import com.mvc.sell.console.pojo.bean.Config; 10 | import com.mvc.sell.console.pojo.bean.Transaction; 11 | import com.mvc.sell.console.pojo.dto.TransactionDTO; 12 | import com.mvc.sell.console.pojo.vo.TransactionVO; 13 | import com.mvc.sell.console.service.ethernum.ContractService; 14 | import com.mvc.sell.console.util.BeanUtil; 15 | import com.mvc.sell.console.util.Web3jUtil; 16 | import lombok.extern.log4j.Log4j; 17 | import org.springframework.beans.factory.annotation.Autowired; 18 | import org.springframework.beans.factory.annotation.Value; 19 | import org.springframework.scheduling.annotation.Async; 20 | import org.springframework.stereotype.Service; 21 | import org.springframework.util.Assert; 22 | import org.springframework.util.StringUtils; 23 | import org.web3j.protocol.Web3j; 24 | import org.web3j.protocol.admin.Admin; 25 | import org.web3j.protocol.admin.methods.response.NewAccountIdentifier; 26 | import org.web3j.protocol.admin.methods.response.PersonalUnlockAccount; 27 | import org.web3j.protocol.core.DefaultBlockParameter; 28 | import org.web3j.protocol.core.DefaultBlockParameterName; 29 | import org.web3j.protocol.core.methods.response.EthGetBalance; 30 | import org.web3j.protocol.core.methods.response.EthGetTransactionReceipt; 31 | import org.web3j.protocol.core.methods.response.EthSendTransaction; 32 | import org.web3j.tx.Contract; 33 | import rx.Subscription; 34 | import rx.functions.Action1; 35 | 36 | import java.io.IOException; 37 | import java.math.BigDecimal; 38 | import java.math.BigInteger; 39 | import java.util.List; 40 | 41 | /** 42 | * TransactionService 43 | * 44 | * @author qiyichen 45 | * @create 2018/3/13 12:06 46 | */ 47 | @Service 48 | @Log4j 49 | public class TransactionService extends BaseService { 50 | 51 | @Autowired 52 | Web3j web3j; 53 | @Autowired 54 | Admin admin; 55 | @Autowired 56 | ProjectService projectService; 57 | @Autowired 58 | AccountService accountService; 59 | @Autowired 60 | ConfigService configService; 61 | @Value("${wallet.password}") 62 | String password; 63 | @Value("${wallet.user}") 64 | String defaultUser; 65 | @Value("${wallet.coldUser}") 66 | String coldUser; 67 | @Value("${wallet.eth}") 68 | BigDecimal ethLimit; 69 | @Autowired 70 | ContractService contractService; 71 | 72 | public final static BigInteger DEFAULT_GAS_PRICE = Contract.GAS_PRICE.divide(BigInteger.valueOf(5)); 73 | public final static BigInteger DEFAULT_GAS_LIMIT = Contract.GAS_LIMIT.divide(BigInteger.valueOf(10)); 74 | 75 | public PageInfo transaction(TransactionDTO transactionDTO) { 76 | transactionDTO.setOrderId(StringUtils.isEmpty(transactionDTO.getOrderId()) ? null : transactionDTO.getOrderId()); 77 | Transaction transaction = (Transaction) BeanUtil.copyProperties(transactionDTO, new Transaction()); 78 | List list = transactionMapper.select(transaction); 79 | PageInfo pageInfo = new PageInfo(list); 80 | PageInfo result = (PageInfo) BeanUtil.beanList2VOList(pageInfo, TransactionVO.class); 81 | result.getList().forEach(obj -> obj.setTokenName(configService.getNameByTokenId(obj.getTokenId()))); 82 | return result; 83 | } 84 | 85 | public void approval(BigInteger id, Integer status, String hash) throws Exception { 86 | Assert.isTrue(status != 2, MessageConstants.getMsg("STATUS_ERROR")); 87 | Transaction transaction = new Transaction(); 88 | transaction.setId(id); 89 | transaction.setStatus(status); 90 | transactionMapper.updateByPrimaryKeySelective(transaction); 91 | setBalance(id, status); 92 | // 发起提币 93 | sendValue(id, status, hash); 94 | } 95 | 96 | private void setBalance(BigInteger id, Integer status) { 97 | if (status.equals(9)) { 98 | Transaction transaction = new Transaction(); 99 | transaction.setId(id); 100 | transaction = transactionMapper.selectByPrimaryKey(transaction); 101 | capitalMapper.updateBalance(transaction.getUserId(), transaction.getTokenId(), transaction.getNumber()); 102 | } 103 | } 104 | 105 | private void sendValue(BigInteger id, Integer status, String hash) throws Exception { 106 | if (status.equals(1)) { 107 | Assert.notNull(hash, "hash地址不能为空"); 108 | Transaction transaction = new Transaction(); 109 | transaction.setId(id); 110 | transaction = transactionMapper.selectByPrimaryKey(transaction); 111 | // String contractAddress = null; 112 | // BigInteger value = Web3jUtil.getWei(transaction.getRealNumber(), transaction.getTokenId(), redisTemplate); 113 | // contractAddress = getContractAddressByTokenId(transaction); 114 | // String hash = sendTransaction(defaultUser, transaction.getToAddress(), contractAddress, value, true); 115 | transaction.setHash(hash); 116 | EthGetTransactionReceipt result = web3j.ethGetTransactionReceipt(hash).send(); 117 | if (null != result && null != result.getResult() && !result.hasError() && result.getTransactionReceipt().get().getStatus().equalsIgnoreCase("0x1")) { 118 | transaction.setStatus(CommonConstants.STATUS_SUCCESS); 119 | } else { 120 | redisTemplate.opsForValue().set(RedisConstants.LISTEN_HASH + "#" + hash, 1); 121 | } 122 | transactionMapper.updateByPrimaryKeySelective(transaction); 123 | } 124 | } 125 | 126 | private String getContractAddressByTokenId(Transaction transaction) { 127 | return configService.getByTokenId(transaction.getTokenId()).getContractAddress(); 128 | } 129 | 130 | private String sendTransaction(String fromAddress, String toAddress, String contractAddress, BigInteger realNumber, Boolean listen) throws Exception { 131 | PersonalUnlockAccount flag = admin.personalUnlockAccount(fromAddress, password).send(); 132 | Assert.isTrue(flag.accountUnlocked(), "unlock error"); 133 | org.web3j.protocol.core.methods.request.Transaction transaction = new org.web3j.protocol.core.methods.request.Transaction( 134 | fromAddress, 135 | null, 136 | DEFAULT_GAS_PRICE, 137 | DEFAULT_GAS_LIMIT, 138 | toAddress, 139 | realNumber, 140 | null 141 | ); 142 | EthSendTransaction result = null; 143 | if (null == contractAddress) { 144 | // send eth 145 | result = web3j.ethSendTransaction(transaction).send(); 146 | } else { 147 | // send token 148 | result = contractService.eth_sendTransaction(transaction, contractAddress); 149 | } 150 | Assert.isTrue(result != null && !result.hasError(), null != result.getError() ? result.getError().getMessage() : "发送失败"); 151 | if (listen) { 152 | redisTemplate.opsForValue().set(RedisConstants.LISTEN_HASH + "#" + result.getTransactionHash(), 1); 153 | } 154 | return result.getTransactionHash(); 155 | } 156 | 157 | @Async 158 | public void startListen() throws InterruptedException { 159 | try { 160 | // listen new transaction 161 | newListen(); 162 | } catch (Exception e) { 163 | Thread.sleep(10000); 164 | startListen(); 165 | } 166 | } 167 | 168 | private void newListen() throws InterruptedException { 169 | Subscription subscribe = null; 170 | try { 171 | subscribe = web3j.transactionObservable().subscribe( 172 | tx -> listenTx(tx, false), 173 | getOnError() 174 | ); 175 | } catch (Exception e) { 176 | e.printStackTrace(); 177 | } 178 | while (true) { 179 | if (null == subscribe || subscribe.isUnsubscribed()) { 180 | Thread.sleep(10000); 181 | newListen(); 182 | } 183 | } 184 | } 185 | 186 | private Action1 getOnError() { 187 | return new Action1() { 188 | @Override 189 | public void call(Throwable throwable) { 190 | log.error(throwable); 191 | } 192 | }; 193 | } 194 | 195 | private void listenTx(org.web3j.protocol.core.methods.response.Transaction tx, Boolean updateLastBlockNumber) { 196 | addressHandler(tx); 197 | hashHandler(tx); 198 | if (updateLastBlockNumber) { 199 | redisTemplate.opsForValue().set(RedisConstants.LAST_BOLCK_NUMBER, tx.getBlockNumber()); 200 | } 201 | } 202 | 203 | private void hashHandler(org.web3j.protocol.core.methods.response.Transaction tx) { 204 | try { 205 | 206 | String key = RedisConstants.LISTEN_HASH + "#" + tx.getHash(); 207 | String hash = tx.getHash(); 208 | if (!redisTemplate.hasKey(key)) { 209 | return; 210 | } 211 | Transaction transaction = new Transaction(); 212 | transaction.setHash(hash); 213 | transaction = transactionMapper.selectOne(transaction); 214 | if (null == transaction) { 215 | return; 216 | } 217 | if (web3j.ethGetTransactionByHash(hash).send().hasError()) { 218 | transaction.setStatus(CommonConstants.ERROR); 219 | } else { 220 | transaction.setStatus(CommonConstants.STATUS_SUCCESS); 221 | } 222 | transactionMapper.updateByPrimaryKeySelective(transaction); 223 | redisTemplate.delete(key); 224 | } catch (Exception e) { 225 | log.error(e); 226 | } 227 | } 228 | 229 | private void addressHandler(org.web3j.protocol.core.methods.response.Transaction tx) { 230 | String to = Web3jUtil.getTo(tx); 231 | String key = RedisConstants.LISTEN_ETH_ADDR + "#" + to; 232 | String hash = tx.getHash(); 233 | BigInteger userId = (BigInteger) redisTemplate.opsForValue().get(key); 234 | if (null == userId) { 235 | return; 236 | } 237 | if (existHash(hash)) { 238 | return; 239 | } 240 | BigInteger tokenId = getTokenId(tx); 241 | Config config = configService.get(tokenId); 242 | if (null == config) { 243 | return; 244 | } 245 | // 充值 246 | Transaction transaction = new Transaction(); 247 | transaction.setHash(hash); 248 | transaction.setUserId(userId); 249 | transaction.setTokenId(tokenId); 250 | transaction.setOrderId(getOrderId(CommonConstants.ORDER_RECHARGE)); 251 | transaction.setType(CommonConstants.RECHARGE); 252 | transaction.setStatus(CommonConstants.STATUS_SUCCESS); 253 | transaction.setToAddress(to); 254 | transaction.setFromAddress(tx.getFrom()); 255 | BigInteger value = Web3jUtil.isContractTx(tx) ? new BigInteger(tx.getInput().substring(tx.getInput().length() - 64), 16) : tx.getValue(); 256 | transaction.setNumber(Web3jUtil.getValue(value, transaction.getTokenId(), redisTemplate)); 257 | transaction.setPoundage(0f); 258 | transaction.setRealNumber(transaction.getNumber()); 259 | transactionMapper.insertSelective(transaction); 260 | // update balance 261 | updateBalance(transaction); 262 | // transfer balance 263 | this.transferBalance(transaction, coldUser); 264 | } 265 | 266 | private void updateBalance(Transaction transaction) { 267 | Capital capital = new Capital(); 268 | capital.setUserId(transaction.getUserId()); 269 | capital.setTokenId(transaction.getTokenId()); 270 | Capital capitalTemp = capitalMapper.selectOne(capital); 271 | if (null == capitalTemp) { 272 | capital.setBalance(transaction.getNumber()); 273 | capitalMapper.insert(capital); 274 | } else { 275 | capitalMapper.updateBalance(transaction.getUserId(), transaction.getTokenId(), transaction.getNumber()); 276 | } 277 | } 278 | 279 | @Async 280 | public void transferBalance(Transaction transaction, String address) { 281 | try { 282 | EthGetBalance result = web3j.ethGetBalance(transaction.getToAddress(), DefaultBlockParameterName.LATEST).send(); 283 | BigInteger needBalance = TransactionService.DEFAULT_GAS_LIMIT.multiply(TransactionService.DEFAULT_GAS_PRICE); 284 | BigInteger sendBalance = result.getBalance().subtract(needBalance); 285 | if (sendGasIfNull(transaction, result, needBalance)) { 286 | return; 287 | } 288 | String contractAddress = getContractAddressByTokenId(transaction); 289 | if (!transaction.getTokenId().equals(BigInteger.ZERO)) { 290 | // erc20 token 291 | sendBalance = contractService.balanceOf(contractAddress, transaction.getToAddress()); 292 | } 293 | sendTransaction(transaction.getToAddress(), address, contractAddress, sendBalance, false); 294 | } catch (Exception e) { 295 | e.printStackTrace(); 296 | log.error(e.getMessage()); 297 | } 298 | } 299 | 300 | private boolean sendGasIfNull(Transaction transaction, EthGetBalance result, BigInteger needBalance) throws IOException { 301 | if (!result.hasError() && result.getBalance().compareTo(BigInteger.ZERO) == 0) { 302 | org.web3j.protocol.core.methods.request.Transaction trans = new org.web3j.protocol.core.methods.request.Transaction( 303 | defaultUser, 304 | null, 305 | DEFAULT_GAS_PRICE, 306 | DEFAULT_GAS_LIMIT, 307 | transaction.getToAddress(), 308 | needBalance, 309 | null 310 | ); 311 | admin.personalUnlockAccount(defaultUser, password); 312 | web3j.ethSendTransaction(trans).send(); 313 | redisTemplate.opsForList().leftPush(RedisConstants.GAS_QUENE, transaction); 314 | return true; 315 | } 316 | return false; 317 | } 318 | 319 | private BigInteger getTokenId(org.web3j.protocol.core.methods.response.Transaction tx) { 320 | if (Web3jUtil.isContractTx(tx)) { 321 | BigInteger tokenId = configService.getIdByContractAddress(tx.getTo()); 322 | return tokenId; 323 | } else { 324 | return BigInteger.ZERO; 325 | } 326 | } 327 | 328 | private Boolean existHash(String hash) { 329 | Transaction transaction = new Transaction(); 330 | transaction.setHash(hash); 331 | if (null != transactionMapper.selectOne(transaction)) { 332 | // 充值记录已存在, 充值不存在成功以外的状态 333 | return true; 334 | } 335 | return false; 336 | } 337 | 338 | private void historyListen() throws InterruptedException { 339 | BigInteger lastBlockNumber = (BigInteger) redisTemplate.opsForValue().get(RedisConstants.LAST_BOLCK_NUMBER); 340 | if (null == lastBlockNumber) { 341 | lastBlockNumber = BigInteger.ZERO; 342 | } 343 | Subscription subscription = web3j.replayTransactionsObservable(DefaultBlockParameter.valueOf(lastBlockNumber), DefaultBlockParameterName.LATEST).subscribe( 344 | tx -> listenTx(tx, true), 345 | getOnError() 346 | ); 347 | while (true) { 348 | if (null == subscription || subscription.isUnsubscribed()) { 349 | Thread.sleep(10000); 350 | historyListen(); 351 | } 352 | } 353 | } 354 | 355 | public Integer newAddress() throws IOException { 356 | Account account = null; 357 | Integer num = 0; 358 | while (null != (account = accountService.getNonAddress())) { 359 | NewAccountIdentifier result = admin.personalNewAccount(password).send(); 360 | account.setAddressEth(result.getAccountId()); 361 | accountService.update(account); 362 | redisTemplate.opsForValue().set(RedisConstants.LISTEN_ETH_ADDR + "#" + result.getAccountId(), account.getId()); 363 | num++; 364 | } 365 | return num; 366 | } 367 | 368 | public Integer sendGas() { 369 | Integer number = 0; 370 | while (redisTemplate.opsForList().size(RedisConstants.GAS_QUENE) > 0) { 371 | Transaction transaction = (Transaction) redisTemplate.opsForList().rightPop(RedisConstants.GAS_QUENE); 372 | transferBalance(transaction, defaultUser); 373 | number++; 374 | } 375 | return number; 376 | } 377 | 378 | public void initConfig() { 379 | configService.initUnit(); 380 | } 381 | 382 | @Async 383 | public void startHistory() throws InterruptedException { 384 | try { 385 | // listen history transaction 386 | historyListen(); 387 | } catch (Exception e) { 388 | Thread.sleep(10000); 389 | startHistory(); 390 | } 391 | } 392 | } 393 | --------------------------------------------------------------------------------