├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── docker ├── apollo │ ├── db │ │ ├── ApolloConfigDB.sql │ │ └── ApolloPortalDB.sql │ ├── docker-compose.yml │ └── init │ │ └── init.sql ├── elastic-search │ ├── README.md │ └── logstash │ │ ├── conf.d │ │ ├── mysql.conf │ │ ├── mysql.jar │ │ └── wanxinp2p_project.sql │ │ └── config │ │ └── logstash.yml ├── mysql │ ├── db │ │ ├── hmily.sql │ │ ├── init.sql │ │ ├── minio.sql │ │ ├── p2p_account.sql │ │ ├── p2p_bank_depository.sql │ │ ├── p2p_consumer.sql │ │ ├── p2p_depository_agent.sql │ │ ├── p2p_repayment.sql │ │ ├── p2p_transaction_0.sql │ │ ├── p2p_transaction_1.sql │ │ └── p2p_uaa.sql │ └── docker-compose.yml ├── redis │ └── README.md ├── rocketmq │ ├── README.MD │ └── conf │ │ └── broker.conf └── zookeeper │ └── README.md ├── pom.xml ├── resource └── image │ ├── alipays.png │ ├── init-01.png │ ├── init-02.png │ ├── log.png │ └── wechats.png ├── wanxinp2p-account-service ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── account │ │ ├── AccountServiceApplication.java │ │ ├── common │ │ ├── AccountErrorCode.java │ │ └── GlobalExceptionHandler.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── WebMvcConfiguration.java │ │ ├── controller │ │ └── AccountController.java │ │ ├── entity │ │ └── Account.java │ │ ├── mapper │ │ ├── AccountMapper.java │ │ └── AccountMapper.xml │ │ └── service │ │ ├── AccountService.java │ │ ├── AccountServiceImpl.java │ │ └── SmsService.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ ├── hmily.yml │ └── log4j2-dev.xml ├── wanxinp2p-api ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── wanxin │ └── api │ ├── account │ ├── AccountAPI.java │ └── model │ │ ├── AccountDTO.java │ │ ├── AccountLoginDTO.java │ │ ├── AccountRegisterDTO.java │ │ └── LoginUser.java │ ├── consumer │ ├── ConsumerAPI.java │ └── model │ │ ├── BalanceDetailsDTO.java │ │ ├── BankCardDTO.java │ │ ├── BorrowerDTO.java │ │ ├── ConsumerDTO.java │ │ ├── ConsumerDetailsDTO.java │ │ ├── ConsumerRegisterDTO.java │ │ ├── ConsumerRequest.java │ │ ├── FileTokenDTO.java │ │ ├── IdCardDTO.java │ │ ├── RechargeRequest.java │ │ └── WithdrawRequest.java │ ├── depository │ ├── DepositoryAgentAPI.java │ └── model │ │ ├── DepositoryBaseResponse.java │ │ ├── DepositoryConsumerResponse.java │ │ ├── DepositoryRechargeResponse.java │ │ ├── DepositoryRecordDTO.java │ │ ├── DepositoryResponseDTO.java │ │ ├── DepositoryWithdrawResponse.java │ │ ├── GatewayRequest.java │ │ ├── LoanDetailRequest.java │ │ ├── LoanRequest.java │ │ ├── ProjectRequestDataDTO.java │ │ └── UserAutoPreTransactionRequest.java │ ├── repayment │ ├── RepaymentAPI.java │ └── model │ │ ├── EqualInterestRepayment.java │ │ ├── EqualPrincipalRepayment.java │ │ ├── RepaymentDetailRequest.java │ │ ├── RepaymentPlanDTO.java │ │ └── RepaymentRequest.java │ ├── search │ ├── ContentSearchAPI.java │ └── model │ │ └── ProjectQueryParamsDTO.java │ └── transaction │ ├── TransactionAPI.java │ └── model │ ├── DateJsonDeserializer.java │ ├── ModifyProjectStatusDTO.java │ ├── ProjectDTO.java │ ├── ProjectInvestDTO.java │ ├── ProjectQueryDTO.java │ ├── ProjectWithTendersDTO.java │ ├── TenderDTO.java │ └── TenderOverviewDTO.java ├── wanxinp2p-common ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── wanxin │ └── common │ ├── cache │ └── Cache.java │ ├── domain │ ├── BusinessException.java │ ├── CodePrefixCode.java │ ├── CommonErrorCode.java │ ├── DepositoryReturnCode.java │ ├── ErrorCode.java │ ├── PageRequestParams.java │ ├── PageVO.java │ ├── PreprocessBusinessTypeCode.java │ ├── ProjectCode.java │ ├── RepaymentWayCode.java │ ├── RestResponse.java │ └── StatusCode.java │ └── util │ ├── Base64Util.java │ ├── CodeNoUtil.java │ ├── CommonUtil.java │ ├── DateUtil.java │ ├── EncryptUtil.java │ ├── FileUtil.java │ ├── HttpUtil.java │ ├── IPUtil.java │ ├── JsonUtil.java │ ├── MD5Util.java │ ├── OkHttpUtil.java │ ├── PasswordUtil.java │ ├── RSAUtil.java │ └── StringUtil.java ├── wanxinp2p-consumer-service ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── consumer │ │ ├── ConsumerServiceApplication.java │ │ ├── agent │ │ ├── AccountApiAgent.java │ │ └── DepositoryAgentApiAgent.java │ │ ├── common │ │ ├── ConsumerErrorCode.java │ │ ├── GlobalExceptionHandler.java │ │ └── SecurityUtil.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── WebMvcConfiguration.java │ │ ├── controller │ │ └── ConsumerController.java │ │ ├── entity │ │ ├── BankCard.java │ │ ├── Consumer.java │ │ ├── ConsumerDetails.java │ │ ├── RechargeRecord.java │ │ └── WithdrawRecord.java │ │ ├── interceptor │ │ └── TokenInterceptor.java │ │ ├── mapper │ │ ├── BankCardMapper.java │ │ ├── BankCardMapper.xml │ │ ├── ConsumerDetailsMapper.java │ │ ├── ConsumerDetailsMapper.xml │ │ ├── ConsumerMapper.java │ │ ├── ConsumerMapper.xml │ │ ├── RechargeRecordMapper.java │ │ ├── RechargeRecordMapper.xml │ │ ├── WithdrawRecordMapper.java │ │ └── WithdrawRecordMapper.xml │ │ ├── message │ │ └── GatewayNotifyConsumer.java │ │ ├── service │ │ ├── BankCardService.java │ │ ├── BankCardServiceImpl.java │ │ ├── ConsumerDetailsService.java │ │ ├── ConsumerDetailsServiceImpl.java │ │ ├── ConsumerService.java │ │ └── ConsumerServiceImpl.java │ │ └── utils │ │ ├── ApolloConfigUtil.java │ │ ├── BaiDuOrcAuthServiceUtil.java │ │ ├── BaiDuOrcIdCardUtil.java │ │ ├── Base64Util.java │ │ ├── CheckBankCardUtil.java │ │ ├── GsonUtils.java │ │ ├── HttpUtil.java │ │ ├── IdCardUtil.java │ │ └── OkHttpUtil.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ ├── hmily.yml │ └── log4j2-dev.xml ├── wanxinp2p-content-search-service ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── search │ │ ├── ContentSearchServiceApplication.java │ │ ├── common │ │ ├── constant │ │ │ └── ContentSearchErrorCode.java │ │ └── intercept │ │ │ └── GlobalExceptionHandler.java │ │ ├── config │ │ ├── ElasticsearchConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── WebMvcConfiguration.java │ │ ├── controller │ │ └── ContentSearchController.java │ │ └── service │ │ ├── ContentSearchService.java │ │ └── ContentSearchServiceImpl.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ └── log4j2-dev.xml ├── wanxinp2p-depository-agent-service ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── depository │ │ ├── DepositoryAgentServiceApplication.java │ │ ├── common │ │ ├── cache │ │ │ └── RedisCache.java │ │ ├── constant │ │ │ ├── DepositoryErrorCode.java │ │ │ └── DepositoryRequestTypeCode.java │ │ └── intercept │ │ │ └── GlobalExceptionHandler.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── RedisConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── WebConfig.java │ │ ├── controller │ │ ├── DepositoryAgentController.java │ │ └── DepositoryNotifyController.java │ │ ├── entity │ │ └── DepositoryRecord.java │ │ ├── interceptor │ │ ├── DepositoryNotifyVerificationInterceptor.java │ │ └── SignatureInterceptor.java │ │ ├── mapper │ │ ├── DepositoryRecordMapper.java │ │ └── DepositoryRecordMapper.xml │ │ ├── message │ │ └── GatewayMessageProducer.java │ │ └── service │ │ ├── ConfigService.java │ │ ├── DepositoryRecordService.java │ │ ├── DepositoryRecordServiceImpl.java │ │ └── OkHttpService.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ └── log4j2-dev.xml ├── wanxinp2p-discover-server ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── discover │ │ └── DiscoverServerApplication.java │ └── resources │ ├── application-dev.yml │ ├── application.yml │ └── log4j2-dev.xml ├── wanxinp2p-gateway-server ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── gateway │ │ ├── GatewayServerApplication.java │ │ ├── common │ │ └── util │ │ │ └── HttpUtil.java │ │ ├── config │ │ ├── ClientDefaultAccessTokenConverter.java │ │ ├── JWTConfig.java │ │ ├── ResourceServerConfig.java │ │ ├── RestAccessDeniedHandler.java │ │ ├── RestOAuth2AuthExceptionEntryPoint.java │ │ └── ZuulConfig.java │ │ └── filter │ │ └── AuthFilter.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ └── log4j2-dev.xml ├── wanxinp2p-repayment-service ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── repayment │ │ ├── RepaymentServiceApplication.java │ │ ├── agent │ │ └── DepositoryAgentApiAgent.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── SchedulerConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── WebConfig.java │ │ ├── controller │ │ └── RepaymentController.java │ │ ├── entity │ │ ├── ReceivableDetail.java │ │ ├── ReceivablePlan.java │ │ ├── RepaymentDetail.java │ │ └── RepaymentPlan.java │ │ ├── interceptor │ │ └── TokenInterceptor.java │ │ ├── job │ │ └── RepaymentSimpleJob.java │ │ ├── mapper │ │ ├── ReceivableDetailMapper.java │ │ ├── ReceivableDetailMapper.xml │ │ ├── ReceivablePlanMapper.java │ │ ├── ReceivablePlanMapper.xml │ │ ├── RepaymentDetailMapper.java │ │ ├── RepaymentDetailMapper.xml │ │ ├── RepaymentPlanMapper.java │ │ └── RepaymentPlanMapper.xml │ │ ├── message │ │ ├── ConfirmRepaymentConsumer.java │ │ ├── ConfirmRepaymentTransactionListener.java │ │ ├── RepaymentProducer.java │ │ └── StartRepaymentMessageConsumer.java │ │ ├── service │ │ ├── RepaymentService.java │ │ └── RepaymentServiceImpl.java │ │ └── utils │ │ └── RepaymentUtil.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ └── log4j2-dev.xml ├── wanxinp2p-transaction-service ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── wanxin │ │ └── transaction │ │ ├── TransactionServiceApplication.java │ │ ├── agent │ │ ├── ConsumerApiAgent.java │ │ ├── ContentSearchApiAgent.java │ │ └── DepositoryAgentApiAgent.java │ │ ├── common │ │ ├── constant │ │ │ ├── ProjectTypeCode.java │ │ │ ├── TradingCode.java │ │ │ ├── TradingStatusCode.java │ │ │ └── TransactionErrorCode.java │ │ ├── intercept │ │ │ └── GlobalExceptionHandler.java │ │ └── utils │ │ │ ├── IncomeCalcUtil.java │ │ │ └── SecurityUtil.java │ │ ├── config │ │ ├── MybatisPlusConfig.java │ │ ├── SwaggerConfiguration.java │ │ └── WebConfig.java │ │ ├── controller │ │ └── TransactionController.java │ │ ├── entity │ │ ├── Project.java │ │ └── Tender.java │ │ ├── interceptor │ │ ├── OpenFeignInterceptor.java │ │ └── TokenInterceptor.java │ │ ├── mapper │ │ ├── ProjectMapper.java │ │ ├── ProjectMapper.xml │ │ ├── TenderMapper.java │ │ └── TenderMapper.xml │ │ ├── message │ │ ├── TransactionListenerImpl.java │ │ └── TransactionProducer.java │ │ └── service │ │ ├── ConfigService.java │ │ ├── ProjectService.java │ │ └── ProjectServiceImpl.java │ └── resources │ ├── apollo-env.properties │ ├── application-dev.yml │ ├── application.yml │ └── log4j2-dev.xml └── wanxinp2p-uaa-service ├── pom.xml └── src └── main ├── java └── com │ └── wanxin │ └── uaa │ ├── UAAServiceApplication.java │ ├── agent │ └── AccountApiAgent.java │ ├── common │ ├── cache │ │ └── RedisCache.java │ ├── intercept │ │ └── GlobalExceptionHandler.java │ └── utils │ │ ├── ApplicationContextHelper.java │ │ ├── GuidGenerator.java │ │ ├── StringUtils.java │ │ └── WebUtils.java │ ├── config │ ├── AuthorizationServer.java │ ├── JWTConfig.java │ ├── OauthUserApprovalHandler.java │ ├── RestOAuth2Exception.java │ ├── RestOAuth2WebResponseExceptionTranslator.java │ ├── RestOAuthExceptionJacksonSerializer.java │ └── SecurityConfig.java │ ├── controller │ └── UUAController.java │ ├── domain │ ├── ClientDefaultAccessTokenConverter.java │ ├── CustomJdbcClientDetailsService.java │ ├── IntegrationUserDetailsAuthenticationHandler.java │ ├── IntegrationUserDetailsAuthenticationProvider.java │ ├── IntegrationWebAuthenticationDetails.java │ ├── IntegrationWebAuthenticationDetailsSource.java │ ├── OauthClientDetails.java │ ├── OauthClientDetailsDto.java │ ├── UnifiedUserAuthenticationConverter.java │ └── UnifiedUserDetails.java │ ├── repository │ ├── OauthClientDetailsRowMapper.java │ ├── OauthRepository.java │ ├── OauthRepositoryJdbc.java │ └── PasswordHandler.java │ └── service │ ├── OauthService.java │ └── OauthServiceImpl.java └── resources ├── apollo-env.properties ├── application-dev.yml ├── application.yml ├── log4j2-dev.xml ├── static └── img │ ├── error.png │ ├── password.png │ └── username.png └── templates ├── login.html ├── oauth_approval.html └── oauth_error.html /.gitattributes: -------------------------------------------------------------------------------- 1 | # *.js linguist-language=java 2 | # *.css linguist-language=java 3 | # *.html linguist-language=java 4 | *.sql linguist-language=java 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | *.iml 26 | .DS_Store 27 | .git 28 | .idea 29 | logs 30 | target 31 | -------------------------------------------------------------------------------- /docker/elastic-search/logstash/conf.d/mysql.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/docker/elastic-search/logstash/conf.d/mysql.jar -------------------------------------------------------------------------------- /docker/elastic-search/logstash/conf.d/wanxinp2p_project.sql: -------------------------------------------------------------------------------- 1 | SELECT 2 | ID AS id, 3 | CONSUMER_ID AS consumerId, 4 | USER_NO AS userNo, 5 | PROJECT_NO AS projectNo, 6 | NAME AS name, 7 | DESCRIPTION AS description, 8 | TYPE AS type, 9 | PERIOD AS period, 10 | ANNUAL_RATE AS annualRate, 11 | BORROWER_ANNUAL_RATE AS borrowerAnnualRate, 12 | COMMISSION_ANNUAL_RATE AS commissionAnnualRate, 13 | REPAYMENT_WAY AS repaymentWay, 14 | AMOUNT AS amount, 15 | PROJECT_STATUS AS projectStatus, 16 | CREATE_DATE AS createDate, 17 | MODIFY_DATE AS modifyDate, 18 | STATUS AS status, 19 | IS_ASSIGNMENT AS isAssignment 20 | FROM 21 | project 22 | WHERE 23 | MODIFY_DATE >= :sql_last_value 24 | -------------------------------------------------------------------------------- /docker/elastic-search/logstash/config/logstash.yml: -------------------------------------------------------------------------------- 1 | # 0.0.0.0:允许任何IP访问 2 | http.host: "0.0.0.0" 3 | # 配置elasticsearch集群地址 4 | xpack.monitoring.elasticsearch.hosts: ["http://192.168.158.164:9200"] 5 | # 允许监控 6 | xpack.monitoring.enabled: true 7 | # 启动时读取配置文件指定 8 | # 指定的该文件可以配置Logstash读取一些文件导入ES 9 | path.config: /usr/share/logstash/conf.d/*.conf 10 | path.logs: /var/log/logstash 11 | -------------------------------------------------------------------------------- /docker/mysql/db/minio.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS `minio`; 2 | CREATE DATABASE `minio` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 3 | USE `minio`; 4 | 5 | SET NAMES utf8mb4; 6 | SET FOREIGN_KEY_CHECKS = 0; 7 | 8 | -- ---------------------------- 9 | -- Table structure for sign 10 | -- ---------------------------- 11 | DROP TABLE IF EXISTS `sign`; 12 | CREATE TABLE `sign` ( 13 | `id` bigint(20) NOT NULL COMMENT '主键', 14 | `username` varchar(56) NOT NULL COMMENT '用户名', 15 | `password` varchar(256) NOT NULL COMMENT '用户密码', 16 | `appId` varchar(256) NOT NULL COMMENT '应用ID', 17 | `salt` varchar(256) NOT NULL COMMENT '加密盐', 18 | `status` char(1) DEFAULT '0' COMMENT '用户状态-0 未开启, 1 开启', 19 | `createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '添加时间', 20 | `updateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间', 21 | PRIMARY KEY (`id`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 23 | 24 | SET FOREIGN_KEY_CHECKS = 1; 25 | -------------------------------------------------------------------------------- /docker/mysql/db/p2p_depository_agent.sql: -------------------------------------------------------------------------------- 1 | DROP DATABASE IF EXISTS `p2p_depository_agent`; 2 | CREATE DATABASE `p2p_depository_agent` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; 3 | USE `p2p_depository_agent`; 4 | 5 | SET NAMES utf8mb4; 6 | SET FOREIGN_KEY_CHECKS = 0; 7 | 8 | -- ---------------------------- 9 | -- Table structure for depository_record 10 | -- ---------------------------- 11 | DROP TABLE IF EXISTS `depository_record`; 12 | CREATE TABLE `depository_record` ( 13 | `ID` bigint(20) NOT NULL COMMENT '主键', 14 | `REQUEST_NO` varchar(50) DEFAULT NULL COMMENT '请求流水号', 15 | `REQUEST_TYPE` varchar(50) DEFAULT NULL COMMENT '请求类型:1.用户信息(新增、编辑)、2.绑卡信息', 16 | `OBJECT_TYPE` varchar(50) DEFAULT NULL COMMENT '业务实体类型', 17 | `OBJECT_ID` bigint(20) DEFAULT NULL COMMENT '关联业务实体标识', 18 | `CREATE_DATE` datetime DEFAULT NULL COMMENT '请求时间', 19 | `IS_SYN` tinyint(1) DEFAULT NULL COMMENT '是否是同步调用', 20 | `REQUEST_STATUS` tinyint(1) DEFAULT NULL COMMENT '数据同步状态', 21 | `CONFIRM_DATE` datetime DEFAULT NULL COMMENT '消息确认时间', 22 | `RESPONSE_DATA` text NULL COMMENT '处理结果', 23 | PRIMARY KEY (`ID`) 24 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='存管交易记录表'; 25 | 26 | SET FOREIGN_KEY_CHECKS = 1; 27 | -------------------------------------------------------------------------------- /docker/mysql/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.1' 2 | services: 3 | mysql: 4 | container_name: 'mysql' 5 | image: 'docker.io/mysql:5.7' 6 | restart: 'always' 7 | network_mode: 'host' 8 | hostname: 'mysql' 9 | environment: 10 | MYSQL_ROOT_PASSWORD: "yueliminvc@outlook.com" 11 | TZ: 'Asia/Shanghai' 12 | ports: 13 | - "3306" 14 | -------------------------------------------------------------------------------- /docker/redis/README.md: -------------------------------------------------------------------------------- 1 | ## 安装Redis4.0 2 | 3 | ```shell script 4 | docker pull redis:4 5 | 6 | docker run --name redis -p 6379:6379 \ 7 | -d redis:4 \ 8 | --requirepass "yueliminvc@outlook.com" \ 9 | --appendonly yes 10 | ``` 11 | -------------------------------------------------------------------------------- /docker/rocketmq/README.MD: -------------------------------------------------------------------------------- 1 | ## 安装RocketMQ 2 | 3 | ```shell script 4 | # rocketmq 5 | docker pull rocketmqinc/rocketmq:4.4.0 6 | 7 | docker run -d -p 9876:9876 \ 8 | -v /root/docker/rocketmq/namesrv/logs:/root/logs \ 9 | -v /root/docker/rocketmq/namesrv/store:/root/store \ 10 | --name rmqnamesrv \ 11 | -e "MAX_POSSIBLE_HEAP=100000000" rocketmqinc/rocketmq:4.4.0 sh mqnamesrv 12 | 13 | docker run -d -p 10911:10911 -p 10909:10909 \ 14 | --privileged=true \ 15 | -v /root/docker/rocketmq/broker/logs:/root/logs \ 16 | -v /root/docker/rocketmq/broker/store:/root/store \ 17 | -v /root/docker/rocketmq/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf \ 18 | --name rmqbroker \ 19 | --link rmqnamesrv:namesrv \ 20 | -e "NAMESRV_ADDR=namesrv:9876" \ 21 | -e "MAX_POSSIBLE_HEAP=200000000" \ 22 | rocketmqinc/rocketmq:4.4.0 sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf 23 | ``` 24 | 25 | ## 监控 26 | 27 | ```shell script 28 | # 监控 29 | docker pull styletang/rocketmq-console-ng 30 | 31 | docker run -d --name rmqconsole \ 32 | -p 8080:8080 \ 33 | -e "JAVA_OPTS=-Drocketmq.namesrv.addr=192.168.158.164:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \ 34 | styletang/rocketmq-console-ng 35 | 36 | systemctl stop firewalld.service 37 | ``` 38 | -------------------------------------------------------------------------------- /docker/rocketmq/conf/broker.conf: -------------------------------------------------------------------------------- 1 | brokerClusterName = DefaultCluster 2 | brokerName = broker-a 3 | brokerId = 0 4 | deleteWhen = 04 5 | fileReservedTime = 48 6 | brokerRole = ASYNC_MASTER 7 | flushDiskType = ASYNC_FLUSH 8 | brokerIP1 = 192.168.158.164 9 | listenPort = 10911 10 | # 是否允许 Broker 自动创建Topic, 建议线下开启, 线上关闭 11 | autoCreateTopicEnable = true 12 | # 是否允许 Broker 自动创建订阅组, 建议线下开启, 线上关闭 13 | autoCreateSubscriptionGroup = true 14 | -------------------------------------------------------------------------------- /docker/zookeeper/README.md: -------------------------------------------------------------------------------- 1 | ## 安装Zookeeper 2 | 3 | ```shell script 4 | docker pull zookeeper:3.6.2 5 | 6 | docker run -id --name zookeeper \ 7 | --privileged=true \ 8 | -p 2181:2181 \ 9 | zookeeper:3.6.2 10 | ``` 11 | -------------------------------------------------------------------------------- /resource/image/alipays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/resource/image/alipays.png -------------------------------------------------------------------------------- /resource/image/init-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/resource/image/init-01.png -------------------------------------------------------------------------------- /resource/image/init-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/resource/image/init-02.png -------------------------------------------------------------------------------- /resource/image/log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/resource/image/log.png -------------------------------------------------------------------------------- /resource/image/wechats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/resource/image/wechats.png -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/AccountServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; 7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 8 | import org.springframework.cloud.openfeign.EnableFeignClients; 9 | import org.springframework.transaction.annotation.EnableTransactionManagement; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @EnableDiscoveryClient 17 | @EnableTransactionManagement 18 | @EnableFeignClients(basePackages = {"com.wanxin.account.agent"}) 19 | @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) 20 | public class AccountServiceApplication { 21 | public static void main(String[] args) { 22 | SpringApplication.run(AccountServiceApplication.class, args); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/common/AccountErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.common; 2 | 3 | import com.wanxin.common.domain.ErrorCode; 4 | 5 | /** 6 | * 异常编码 0成功, -1熔断, -2 标准参数校验不通过, -3会话超时 7 | * 前两位:服务标识 8 | * 中间两位:模块标识 9 | * 后两位:异常标识 10 | * 统一账号服务异常编码 以13开始 11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | public enum AccountErrorCode implements ErrorCode { 17 | E_130101(130101, "用户名已存在"), 18 | E_130104(130104, "用户未注册"), 19 | E_130105(130105, "用户名或密码错误"), 20 | E_140141(140141, "注册失败"), 21 | 22 | E_140151(140151, "获取短信验证码失败"), 23 | E_140152(140152, "验证码错误"); 24 | 25 | private int code; 26 | private String desc; 27 | 28 | private AccountErrorCode(int code, String desc) { 29 | this.code = code; 30 | this.desc = desc; 31 | } 32 | 33 | public static AccountErrorCode setErrorCode(int code) { 34 | for (AccountErrorCode errorCode : AccountErrorCode.values()) { 35 | if (errorCode.getCode() == code) { 36 | return errorCode; 37 | } 38 | } 39 | return null; 40 | } 41 | 42 | @Override 43 | public int getCode() { 44 | return code; 45 | } 46 | 47 | @Override 48 | public String getDesc() { 49 | return desc; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * @author yuelimin 12 | * @version 1.0.0 13 | * @since 1.8 14 | */ 15 | @Configuration 16 | @MapperScan("com.wanxin.account.mapper") 17 | public class MybatisPlusConfig { 18 | @Bean 19 | public PaginationInterceptor paginationInterceptor() { 20 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 21 | paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); 22 | return paginationInterceptor; 23 | } 24 | 25 | @Bean 26 | public PerformanceInterceptor performanceInterceptor() { 27 | return new PerformanceInterceptor(); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Configuration 21 | @EnableSwagger2 22 | @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true") 23 | public class SwaggerConfiguration { 24 | @Bean 25 | public Docket buildDocket() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(buildApiInfo()) 28 | .select() 29 | // 要扫描的API(Controller)基础包 30 | .apis(RequestHandlerSelectors.basePackage("com.wanxin")) 31 | .paths(PathSelectors.any()) 32 | .build(); 33 | } 34 | 35 | private ApiInfo buildApiInfo() { 36 | Contact contact = new Contact("岳立民", "https://github.com/mikuhuyo", "yueliminvc@outlook.com"); 37 | return new ApiInfoBuilder() 38 | .title("万信金融P2P平台-用户服务API文档") 39 | .description("统一账户服务api") 40 | .contact(contact) 41 | .version("1.0.0").build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/entity/Account.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import lombok.Data; 7 | 8 | import java.io.Serializable; 9 | 10 | /** 11 | * @author yuelimin 12 | * @version 1.0.0 13 | * @since 1.8 14 | */ 15 | @Data 16 | @TableName("account") 17 | public class Account implements Serializable { 18 | 19 | private static final long serialVersionUID = 1L; 20 | 21 | /** 22 | * 主键 23 | */ 24 | @TableId("ID") 25 | private Long id; 26 | 27 | /** 28 | * 用户名 29 | */ 30 | @TableField("USERNAME") 31 | private String username; 32 | 33 | /** 34 | * 手机号 35 | */ 36 | @TableField("MOBILE") 37 | private String mobile; 38 | 39 | /** 40 | * 密码 41 | */ 42 | @TableField("PASSWORD") 43 | private String password; 44 | 45 | /** 46 | * 加密盐 47 | */ 48 | @TableField("SALT") 49 | private String salt; 50 | 51 | /** 52 | * 账号状态 53 | */ 54 | @TableField("STATUS") 55 | private Integer status; 56 | 57 | /** 58 | * 域(c:c端用户;b:b端用户) 59 | */ 60 | @TableField("DOMAIN") 61 | private String domain; 62 | 63 | } 64 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/mapper/AccountMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.account.entity.Account; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface AccountMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/mapper/AccountMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/service/AccountService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.service; 2 | 3 | import com.wanxin.api.account.model.AccountDTO; 4 | import com.wanxin.api.account.model.AccountLoginDTO; 5 | import com.wanxin.api.account.model.AccountRegisterDTO; 6 | import com.wanxin.common.domain.RestResponse; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | public interface AccountService { 14 | /** 15 | * 用户登录 16 | * 17 | * @param accountLoginDTO 登录信息 18 | * @return 19 | */ 20 | AccountDTO login(AccountLoginDTO accountLoginDTO); 21 | 22 | /** 23 | * 保存账户 24 | * 25 | * @param accountRegisterDTO 注册用户实体类 26 | * @return 27 | */ 28 | AccountDTO registry(AccountRegisterDTO accountRegisterDTO); 29 | 30 | /** 31 | * 手机号与验证码校验 32 | * 33 | * @param mobile 手机号 34 | * @param key 秘钥 35 | * @param code 验证码 36 | * @return 37 | */ 38 | Integer checkMobile(String mobile, String key, String code); 39 | 40 | /** 41 | * 获取手机验证码 42 | * 43 | * @param mobile 手机号 44 | * @return 45 | */ 46 | RestResponse getSMSCode(String mobile); 47 | } 48 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/java/com/wanxin/account/service/SmsService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.account.service; 2 | 3 | import com.wanxin.account.common.AccountErrorCode; 4 | import com.wanxin.common.domain.BusinessException; 5 | import com.wanxin.common.domain.CommonErrorCode; 6 | import com.wanxin.common.domain.RestResponse; 7 | import com.wanxin.common.util.OkHttpUtil; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.stereotype.Service; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Service 17 | public class SmsService { 18 | @Value("${sms.url}") 19 | private String smsURL; 20 | 21 | @Value("${sms.enable}") 22 | private Boolean smsEnable; 23 | 24 | /** 25 | * 获取手机验证码 26 | * 27 | * @param mobile 手机号 28 | * @return 29 | */ 30 | public RestResponse getSMSCode(String mobile) { 31 | if (smsEnable) { 32 | return OkHttpUtil.post(smsURL + "/generate?effectiveTime=300&name=sms", "{\"mobile\":" + mobile + "}"); 33 | 34 | } 35 | return RestResponse.success(); 36 | } 37 | 38 | /** 39 | * 验证码校验 40 | * 41 | * @param key 秘钥 42 | * @param code 验证码 43 | */ 44 | public void verifySmsCode(String key, String code) { 45 | if (smsEnable) { 46 | StringBuilder params = new StringBuilder("/verify?name=sms"); 47 | params.append("&verificationKey=").append(key).append("&verificationCode=").append(code); 48 | RestResponse smsResponse = OkHttpUtil.post(smsURL + params, ""); 49 | if (smsResponse.getCode() != CommonErrorCode.SUCCESS.getCode() || smsResponse.getResult().toString().equalsIgnoreCase("false")) { 50 | throw new BusinessException(AccountErrorCode.E_140152); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53050 2 | app: 3 | id: account-service 4 | apollo: 5 | meta: http://192.168.158.162:8080 6 | bootstrap: 7 | enabled: true 8 | eagerLoad: 9 | enabled: true 10 | namespaces: application,micro_service.spring-boot-druid,micro_service.spring-boot-http,micro_service.spring-eureka,micro_service.spring-hystrix,micro_service.spring-ribbon,micro_service.spring-boot-redis,micro_service.mybatis-plus,micro_service.spring-rocketmq 11 | 12 | logging: 13 | config: classpath:log4j2-dev.xml 14 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53030 3 | 4 | spring: 5 | application: 6 | name: account-service 7 | main: 8 | banner-mode: 'off' 9 | allow-bean-definition-overriding: true 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-account-service/src/main/resources/hmily.yml: -------------------------------------------------------------------------------- 1 | hmily: 2 | server: 3 | configMode: local 4 | appName: account-service 5 | config: 6 | appName: account-service 7 | serializer: kryo 8 | contextTransmittalMode: threadLocal 9 | scheduledThreadMax: 4 10 | scheduledRecoveryDelay: 60 11 | scheduledCleanDelay: 60 12 | scheduledPhyDeletedDelay: 600 13 | scheduledInitDelay: 30 14 | recoverDelayTime: 60 15 | cleanDelayTime: 180 16 | limit: 200 17 | retryMax: 10 18 | bufferSize: 8192 19 | consumerThreads: 16 20 | asyncRepository: true 21 | autoSql: true 22 | phyDeleted: true 23 | storeDays: 3 24 | repository: mysql 25 | 26 | repository: 27 | database: 28 | driverClassName: com.mysql.cj.jdbc.Driver 29 | url : jdbc:mysql://192.168.158.164:3306/hmily?useUnicode=true&characterEncoding=utf8 30 | username: root 31 | password: yueliminvc@outlook.com 32 | maxActive: 20 33 | minIdle: 10 34 | connectionTimeout: 30000 35 | idleTimeout: 600000 36 | maxLifetime: 1800000 37 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/account/AccountAPI.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.account; 2 | 3 | import com.wanxin.api.account.model.AccountDTO; 4 | import com.wanxin.api.account.model.AccountLoginDTO; 5 | import com.wanxin.api.account.model.AccountRegisterDTO; 6 | import com.wanxin.common.domain.RestResponse; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | public interface AccountAPI { 14 | /** 15 | * 用户登录 16 | * 17 | * @param accountLoginDTO 封装登录请求数据 18 | * @return 19 | */ 20 | RestResponse login(AccountLoginDTO accountLoginDTO); 21 | 22 | /** 23 | * 用户注册 24 | * 25 | * @param accountRegisterDTO 注册信息实体类 26 | * @return 27 | */ 28 | RestResponse registry(AccountRegisterDTO accountRegisterDTO); 29 | 30 | /** 31 | * 校验手机号和验证码 32 | * 33 | * @param mobile 手机号 34 | * @param key 校验标识 35 | * @param code 验证码 36 | * @return 37 | */ 38 | RestResponse checkMobile(String mobile, String key, String code); 39 | 40 | /** 41 | * 获取短信验证码 42 | * 43 | * @param mobile 手机号 44 | * @return 45 | */ 46 | RestResponse getSMSCode(String mobile); 47 | } 48 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/account/model/AccountDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.account.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "AccountDTO", description = "账户信息") 14 | public class AccountDTO { 15 | 16 | @ApiModelProperty("标识") 17 | private Long id; 18 | 19 | @ApiModelProperty("用户名") 20 | private String username; 21 | 22 | @ApiModelProperty("手机号") 23 | private String mobile; 24 | 25 | @ApiModelProperty("账号状态") 26 | private Integer status; 27 | 28 | @ApiModelProperty(" 域(c:c端用户;b:b端用户)") 29 | private String domain; 30 | } 31 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/account/model/AccountLoginDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.account.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | *

9 | * 封装账户登录信息 10 | *

11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Data 17 | @ApiModel(value = "AccountLoginDTO", description = "账户登录信息") 18 | public class AccountLoginDTO { 19 | 20 | @ApiModelProperty("用户名") 21 | private String username; 22 | 23 | @ApiModelProperty("手机号") 24 | private String mobile; 25 | 26 | @ApiModelProperty("密码") 27 | private String password; 28 | 29 | @ApiModelProperty("域(c:c端用户;b:b端用户)") 30 | private String domain; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/account/model/AccountRegisterDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.account.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "AccountRegisterDTO", description = "账户注册信息") 14 | public class AccountRegisterDTO { 15 | 16 | @ApiModelProperty("用户名") 17 | private String username; 18 | 19 | @ApiModelProperty("手机号") 20 | private String mobile; 21 | 22 | @ApiModelProperty("密码") 23 | private String password; 24 | 25 | } 26 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/account/model/LoginUser.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.account.model; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * 当前登录用户 7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | public class LoginUser { 14 | private String tenantId; 15 | private String departmentId; 16 | private String payload; 17 | private String username; 18 | private String mobile; 19 | private String userAuthorities; 20 | private String clientId; 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/BalanceDetailsDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.io.Serializable; 9 | import java.math.BigDecimal; 10 | 11 | /** 12 | *

13 | * 用户余额明细 14 | *

15 | * 16 | * @author yuelimin 17 | * @since 1.8 18 | */ 19 | @Data 20 | @Accessors(chain = true) 21 | @ApiModel(value = "BalanceDetailsDTO", description = "用户余额信息") 22 | public class BalanceDetailsDTO implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | @ApiModelProperty(value = "用户编码,生成唯一,用户在存管系统标识") 27 | private String userNo; 28 | 29 | @ApiModelProperty(value = "账户变动类型.1.增加.2.减少.3.冻结.4解冻") 30 | private Integer changeType; 31 | 32 | @ApiModelProperty(value = "冻结金额") 33 | private BigDecimal freezeAmount; 34 | 35 | @ApiModelProperty(value = "可用余额") 36 | private BigDecimal balance; 37 | 38 | @ApiModelProperty(value = "应用编码") 39 | private String appCode; 40 | 41 | // @ApiModelProperty(value = "账户变动时间") 42 | // private LocalDateTime createDate; 43 | 44 | } 45 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/BankCardDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "BankCardDTO", description = "银行卡信息") 14 | public class BankCardDTO { 15 | 16 | @ApiModelProperty("标识") 17 | private Long id; 18 | 19 | @ApiModelProperty("用户标识") 20 | private Long consumerId; 21 | 22 | @ApiModelProperty("用户实名") 23 | private String fullName; 24 | 25 | @ApiModelProperty("银行编码") 26 | private String bankCode; 27 | 28 | @ApiModelProperty("银行名称") 29 | private String bankName; 30 | 31 | @ApiModelProperty("银行卡号") 32 | private String cardNumber; 33 | 34 | @ApiModelProperty("银行预留手机号") 35 | private String mobile; 36 | 37 | @ApiModelProperty("可用状态") 38 | private Integer status; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/BorrowerDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "BorrowerDTO", description = "借款人用户信息") 14 | public class BorrowerDTO { 15 | 16 | @ApiModelProperty("用户id") 17 | private Long id; 18 | 19 | @ApiModelProperty("用户名") 20 | private String username; 21 | 22 | @ApiModelProperty("真实姓名") 23 | private String fullname; 24 | 25 | @ApiModelProperty("身份证号") 26 | private String idNumber; 27 | 28 | @ApiModelProperty("手机号") 29 | private String mobile; 30 | 31 | @ApiModelProperty("年龄") 32 | private Integer age; 33 | 34 | @ApiModelProperty("生日") 35 | private String birthday; 36 | 37 | @ApiModelProperty("性别") 38 | private String gender; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/ConsumerDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @Data 15 | @ApiModel(value = "ConsumerDTO", description = "平台c端用户信息") 16 | public class ConsumerDTO { 17 | 18 | @ApiModelProperty("用户id") 19 | private Long id; 20 | 21 | @ApiModelProperty("用户名") 22 | private String username; 23 | 24 | @ApiModelProperty("真实姓名") 25 | private String fullname; 26 | 27 | @ApiModelProperty("身份证号") 28 | private String idNumber; 29 | 30 | @ApiModelProperty("用户编码, 用户在存管系统标识, 不允许重复") 31 | private String userNo; 32 | 33 | @ApiModelProperty("手机号") 34 | private String mobile; 35 | 36 | @ApiModelProperty("用户类型, 个人 or 企业, 预留") 37 | private String userType; 38 | 39 | @ApiModelProperty("角色") 40 | private String role; 41 | 42 | @ApiModelProperty("存管授权列表") 43 | private String authList; 44 | 45 | @ApiModelProperty("是否已绑定银行卡") 46 | private Integer isBindCard; 47 | 48 | @ApiModelProperty("启用状态") 49 | private Integer status; 50 | 51 | @ApiModelProperty("是否进行身份校验证") 52 | private Integer isCardAuth; 53 | 54 | @ApiModelProperty("可贷额度") 55 | private BigDecimal loanAmount; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/ConsumerDetailsDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.time.LocalDateTime; 8 | 9 | /** 10 | *

11 | * 封装平台c端用户详细信息 12 | *

13 | * 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | @Data 19 | @ApiModel(value = "ConsumerDetailsDTO", description = "平台c端用户详细信息") 20 | public class ConsumerDetailsDTO { 21 | 22 | @ApiModelProperty("用户id") 23 | private Long id; 24 | 25 | @ApiModelProperty("用户标识") 26 | private Long consumerId; 27 | 28 | @ApiModelProperty("身份证号") 29 | private String idCardNo; 30 | 31 | @ApiModelProperty("身份证照片面标识") 32 | private String idCardPhoto; 33 | 34 | @ApiModelProperty("身份证国徽面标识") 35 | private String idCardEmblem; 36 | 37 | @ApiModelProperty("住址") 38 | private String address; 39 | 40 | @ApiModelProperty("企业邮箱") 41 | private String enterpriseMail; 42 | 43 | @ApiModelProperty("联系人关系") 44 | private String contactRelation; 45 | 46 | @ApiModelProperty("身份证姓名") 47 | private String contactName; 48 | 49 | @ApiModelProperty("联系人电话") 50 | private String contactMobile; 51 | 52 | @ApiModelProperty("创建时间") 53 | private LocalDateTime uploadDate; 54 | 55 | @ApiModelProperty("真实姓名") 56 | private String fullname; 57 | 58 | @ApiModelProperty("身份证号") 59 | private String idNumber; 60 | 61 | } 62 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/ConsumerRegisterDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "ConsumerRegisterDTO", description = "用户注册信息") 14 | public class ConsumerRegisterDTO { 15 | 16 | @ApiModelProperty("用户名") 17 | private String username; 18 | 19 | @ApiModelProperty("手机号") 20 | private String mobile; 21 | 22 | @ApiModelProperty("密码") 23 | private String password; 24 | 25 | @ApiModelProperty("用户角色.B借款人 or I投资人") 26 | private String role; 27 | 28 | @ApiModelProperty("验证码key") 29 | private String key; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/ConsumerRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "ConsumerRequest", description = "平台c端用户开户信息") 14 | public class ConsumerRequest { 15 | 16 | @ApiModelProperty("id") 17 | private Long id; 18 | 19 | @ApiModelProperty("用户名") 20 | private String username; 21 | 22 | @ApiModelProperty("真实姓名") 23 | private String fullname; 24 | 25 | @ApiModelProperty("身份证号") 26 | private String idNumber; 27 | 28 | @ApiModelProperty("银行编码") 29 | private String bankCode; 30 | 31 | @ApiModelProperty("银行卡号") 32 | private String cardNumber; 33 | 34 | @ApiModelProperty("手机号") 35 | private String mobile; 36 | 37 | @ApiModelProperty("角色") 38 | private String role; 39 | 40 | @ApiModelProperty("请求流水号") 41 | private String requestNo; 42 | 43 | @ApiModelProperty("用户编号") 44 | private String userNo; 45 | 46 | @ApiModelProperty("页面回跳 URL") 47 | private String callbackUrl; 48 | 49 | } 50 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/FileTokenDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "FileTokenDTO", description = "上传文件凭证") 14 | public class FileTokenDTO { 15 | @ApiModelProperty("应用ID") 16 | private String appId; 17 | 18 | @ApiModelProperty("ak") 19 | private String accessKey; 20 | 21 | @ApiModelProperty("sk") 22 | private String secretKey; 23 | } 24 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/IdCardDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Data 13 | @ApiModel(value = "IdCardDTO", description = "百度ORC识别身份证信息") 14 | public class IdCardDTO { 15 | @ApiModelProperty("正反面") 16 | private String flag; 17 | 18 | @ApiModelProperty("ORC识别身份证号码") 19 | private String idCardNo; 20 | 21 | @ApiModelProperty("ORC识别身份证姓名") 22 | private String idCardName; 23 | 24 | @ApiModelProperty("ORC识别身份证地址") 25 | private String idCardAddress; 26 | } 27 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/RechargeRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.math.BigDecimal; 9 | 10 | /** 11 | *

12 | * 用户充值请求信息 13 | *

14 | * 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | @Data 20 | @Accessors(chain = true) 21 | @ApiModel("用户充值请求信息") 22 | public class RechargeRequest { 23 | 24 | @ApiModelProperty("标识") 25 | private Long id; 26 | 27 | @ApiModelProperty("用户编号") 28 | private String userNo; 29 | 30 | @ApiModelProperty("请求流水号") 31 | private String requestNo; 32 | 33 | @ApiModelProperty("充值金额") 34 | private BigDecimal amount; 35 | 36 | @ApiModelProperty("页面回调URL") 37 | private String callbackUrl; 38 | } 39 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/consumer/model/WithdrawRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.consumer.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.math.BigDecimal; 9 | 10 | /** 11 | *

12 | * 封装提现请求数据 13 | *

14 | * 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | @Data 20 | @Accessors(chain = true) 21 | @ApiModel("用户提现请求信息") 22 | public class WithdrawRequest { 23 | 24 | @ApiModelProperty("标识") 25 | private Long id; 26 | 27 | @ApiModelProperty("用户编号") 28 | private String userNo; 29 | 30 | @ApiModelProperty("请求流水号") 31 | private String requestNo; 32 | 33 | @ApiModelProperty("提现金额") 34 | private BigDecimal amount; 35 | 36 | @ApiModelProperty("平台佣金") 37 | private BigDecimal commission; 38 | 39 | @ApiModelProperty("页面回调URL") 40 | private String callbackURL; 41 | 42 | @ApiModelProperty("银行卡号") 43 | private String cardNumber; 44 | 45 | @ApiModelProperty("银行预留手机号") 46 | private String mobile; 47 | } 48 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/DepositoryBaseResponse.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | 7 | import java.io.Serializable; 8 | 9 | /** 10 | *

11 | * 返回参数信息基类 12 | *

13 | * 14 | * @author yuelimin 15 | * @since 1.8 16 | */ 17 | @Data 18 | @Accessors(chain = true) 19 | public class DepositoryBaseResponse implements Serializable { 20 | 21 | @ApiModelProperty("返回码") 22 | private String respCode; 23 | 24 | @ApiModelProperty("描述信息") 25 | private String respMsg; 26 | 27 | @ApiModelProperty("交易状态") 28 | private Integer status; 29 | 30 | @ApiModelProperty("请求流水号") 31 | private String requestNo; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/DepositoryConsumerResponse.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.Data; 5 | 6 | /** 7 | *

8 | * 开户返回参数信息 9 | *

10 | * 11 | * @author yuelimin 12 | * @since 1.8 13 | */ 14 | @Data 15 | public class DepositoryConsumerResponse extends DepositoryBaseResponse { 16 | @ApiModelProperty("银行代码") 17 | private String bankCode; 18 | 19 | @ApiModelProperty("银行名称") 20 | private String bankName; 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/DepositoryRechargeResponse.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | *

9 | * 存管充值响应信息 10 | *

11 | * 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | @Data 16 | @ApiModel(value = "RechargeResponse", description = "用户充值请求返回信息") 17 | public class DepositoryRechargeResponse extends DepositoryBaseResponse { 18 | 19 | @ApiModelProperty("交易状态") 20 | private String transactionStatus; 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/DepositoryRecordDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | 8 | import java.io.Serializable; 9 | import java.time.LocalDateTime; 10 | 11 | /** 12 | *

13 | * 存管交易记录表 14 | *

15 | * 16 | * @author yuelimin 17 | * @since 1.8 18 | */ 19 | @Data 20 | @EqualsAndHashCode(callSuper = false) 21 | @ApiModel(value = "DepositoryRecordDTO对象", description = "存管交易记录表") 22 | public class DepositoryRecordDTO implements Serializable { 23 | @ApiModelProperty(value = "主键") 24 | private Long id; 25 | 26 | @ApiModelProperty(value = "请求流水号") 27 | private String requestNo; 28 | 29 | @ApiModelProperty(value = "请求类型:1.用户信息(新增, 编辑) 2.绑卡信息") 30 | private String requestType; 31 | 32 | @ApiModelProperty(value = "业务实体类型") 33 | private String objectType; 34 | 35 | @ApiModelProperty(value = "关联业务实体标识") 36 | private Long objectId; 37 | 38 | @ApiModelProperty(value = "请求时间") 39 | private LocalDateTime createDate; 40 | 41 | @ApiModelProperty(value = "是否是同步调用") 42 | private Integer isSyn; 43 | 44 | @ApiModelProperty(value = "数据同步状态") 45 | private Integer requestStatus; 46 | 47 | @ApiModelProperty(value = "消息确认时间") 48 | private LocalDateTime confirmDate; 49 | 50 | @ApiModelProperty("返回数据") 51 | private String responseData; 52 | } 53 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/DepositoryResponseDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModelProperty; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | *

10 | * 银行存管系统返回str, 转换的json对象 11 | *

12 | * 13 | * @author yuelimin 14 | * @since 1.8 15 | */ 16 | @Data 17 | public class DepositoryResponseDTO implements Serializable { 18 | /** 19 | * 业务数据报文, JSON格式 20 | */ 21 | @ApiModelProperty("业务数据报文,JSON格式") 22 | private T respData; 23 | 24 | /** 25 | * 签名 26 | */ 27 | @ApiModelProperty("签名数据") 28 | private String signature; 29 | } 30 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/DepositoryWithdrawResponse.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | *

9 | * 存管提现响应信息 10 | *

11 | * 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | @Data 16 | @ApiModel(value = "WithdrawResponse", description = "用户提现请求返回信息") 17 | public class DepositoryWithdrawResponse extends DepositoryBaseResponse { 18 | 19 | @ApiModelProperty("交易状态") 20 | private String transactionStatus; 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/GatewayRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | * 与银行存管系统对接使用的签名请求数据 9 | * 10 | * @author yuelimin 11 | * @since 1.8 12 | */ 13 | @Data 14 | @ApiModel(value = "GatewayRequest", description = "与银行存管系统对接使用的签名请求数据") 15 | public class GatewayRequest { 16 | 17 | @ApiModelProperty("请求的存管接口名") 18 | private String serviceName; 19 | 20 | @ApiModelProperty("平台编号, 平台与存管系统签约时获取") 21 | private String platformNo; 22 | 23 | @ApiModelProperty("业务数据报文, json格式") 24 | private String reqData; 25 | 26 | @ApiModelProperty("对reqData参数的签名") 27 | private String signature; 28 | 29 | @ApiModelProperty("银行存管系统地址") 30 | private String depositoryUrl; 31 | } 32 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/LoanDetailRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | *

9 | * 放款明细请求信息 10 | *

11 | * 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | @Data 16 | public class LoanDetailRequest { 17 | /** 18 | * 放款金额 19 | */ 20 | private BigDecimal amount; 21 | 22 | /** 23 | * 预处理业务流水号 24 | */ 25 | private String preRequestNo; 26 | } 27 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/LoanRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 标的满标放款信息 11 | *

12 | * 13 | * @author yuelimin 14 | * @since 1.8 15 | */ 16 | @Data 17 | public class LoanRequest { 18 | /** 19 | * 放款明细 20 | */ 21 | private List details; 22 | 23 | /** 24 | * 平台佣金 25 | */ 26 | private BigDecimal commission; 27 | 28 | /** 29 | * 标的编码 30 | */ 31 | private String projectNo; 32 | 33 | /** 34 | * 请求流水号 35 | */ 36 | private String requestNo; 37 | 38 | /** 39 | * 操作对象id 40 | */ 41 | private Long id; 42 | } 43 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/ProjectRequestDataDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | 7 | /** 8 | *

9 | * 银行存管系统创建标的reqData参数实体 10 | *

11 | * 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | @Data 16 | public class ProjectRequestDataDTO { 17 | /** 18 | * 请求流水号 19 | */ 20 | private String requestNo; 21 | /** 22 | * 平台用户编号 23 | */ 24 | private String userNo; 25 | /** 26 | * 标的号 27 | */ 28 | private String projectNo; 29 | /** 30 | * 标的金额 31 | */ 32 | private BigDecimal projectAmount; 33 | /** 34 | * 标的名称 35 | */ 36 | private String projectName; 37 | /** 38 | * 标的描述 39 | */ 40 | private String projectDesc; 41 | /** 42 | * 标的产品类型 43 | */ 44 | private String projectType; 45 | /** 46 | * 标的期限 47 | */ 48 | private Integer projectPeriod; 49 | /** 50 | * 年化利率( 5%只传5 ) 51 | */ 52 | private BigDecimal annualRate; 53 | /** 54 | * 还款方式 55 | */ 56 | private String repaymentWay; 57 | /** 58 | * 是否是债权出让标 59 | */ 60 | private Integer isAssignment; 61 | } 62 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/depository/model/UserAutoPreTransactionRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.depository.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | *

11 | * 预授权处理请求信息 12 | *

13 | * 14 | * @author yuelimin 15 | * @since 1.8 16 | */ 17 | @Data 18 | @ApiModel(value = "UserAutoPreTransactionRequest", description = "预授权处理请求信息") 19 | public class UserAutoPreTransactionRequest { 20 | 21 | @ApiModelProperty("冻结金额") 22 | private BigDecimal amount; 23 | 24 | @ApiModelProperty("请求流水号") 25 | private String requestNo; 26 | 27 | @ApiModelProperty("投资人用户编码") 28 | private String userNo; 29 | 30 | @ApiModelProperty("预处理业务类型") 31 | private String bizType; 32 | 33 | @ApiModelProperty("红包金额") 34 | private BigDecimal preMarketingAmount; 35 | 36 | @ApiModelProperty("备注") 37 | private String remark; 38 | 39 | @ApiModelProperty("标的号") 40 | private String projectNo; 41 | 42 | @ApiModelProperty("债权出让流水号, 购买债权时需填此参数") 43 | private String creditsaleRequestNo; 44 | 45 | @ApiModelProperty("预处理业务ID") 46 | private Long id; 47 | } 48 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/repayment/RepaymentAPI.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.repayment; 2 | 3 | import com.wanxin.api.transaction.model.ProjectWithTendersDTO; 4 | import com.wanxin.common.domain.RestResponse; 5 | 6 | /** 7 | * @author yuelimin 8 | * @version 1.0.0 9 | * @since 1.8 10 | */ 11 | public interface RepaymentAPI { 12 | /** 13 | * 启动还款 14 | * 15 | * @param projectWithTendersDTO 16 | * @return 17 | */ 18 | RestResponse startRepayment(ProjectWithTendersDTO projectWithTendersDTO); 19 | } 20 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/repayment/model/EqualInterestRepayment.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.repayment.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.Map; 7 | 8 | /** 9 | *

10 | * 等额本息还款: 即借款人每月按相等的金额偿还贷款本息, 其中每月贷款利息按月初剩余贷款本金计算并逐月结清, 11 | * 把按揭贷款的本金总额与利息总额相加, 然后平均分摊到还款期限的每个月中. 12 | * 作为还款人, 每个月还给银行固定金额, 但每月还款额中的本金比重逐月递增, 利息比重逐月递减. 13 | *

14 | * 15 | * @author yuelimin 16 | * @since 1.8 17 | */ 18 | @Data 19 | public class EqualInterestRepayment { 20 | /** 21 | * 每月还款本息 22 | */ 23 | private BigDecimal amount; 24 | /** 25 | * 每月还款利息, 期数:利息 26 | */ 27 | private Map interestMap; 28 | /** 29 | * 每月还款本金, 期数:本金 30 | */ 31 | private Map principalMap; 32 | /** 33 | * 本息总和 34 | */ 35 | private BigDecimal totalAmount; 36 | /** 37 | * 总利息 38 | */ 39 | private BigDecimal totalInterest; 40 | /** 41 | * 平台抽息 42 | */ 43 | private Map commissionMap; 44 | } 45 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/repayment/model/EqualPrincipalRepayment.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.repayment.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.Map; 7 | 8 | /** 9 | *

10 | * 等额本金: 是指一种贷款的还款方式, 是在还款期内把贷款数总额等分, 11 | * 每月偿还同等数额的本金和剩余贷款在该月所产生的利息, 这样由于每月的还款本金额固定, 12 | * 而利息越来越少, 借款人起初还款压力较大, 但是随时间的推移每月还款数也越来越少. 13 | * 公式: 每月偿还本金=(贷款本金÷还款月数) + (贷款本金-已归还本金累计额) × 月利率 14 | *

15 | * 16 | * @author yuelimin 17 | * @since 1.8 18 | */ 19 | @Data 20 | public class EqualPrincipalRepayment { 21 | /** 22 | * 每月还款本息 23 | */ 24 | private Map amountMap; 25 | /** 26 | * 每月还款利息, 期数:利息 27 | */ 28 | private Map interestMap; 29 | /** 30 | * 每月还款本金, 期数:本金 31 | */ 32 | private BigDecimal principal; 33 | /** 34 | * 本息总和 35 | */ 36 | private BigDecimal totalAmount; 37 | /** 38 | * 总利息 39 | */ 40 | private BigDecimal totalInterest; 41 | /** 42 | * 平台抽息 43 | */ 44 | private Map commissionMap; 45 | } 46 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/repayment/model/RepaymentDetailRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.repayment.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | *

11 | * 还款明细请求信息 12 | *

13 | * 14 | * @author yuelimin 15 | * @since 1.8 16 | */ 17 | @Data 18 | @ApiModel(value = "RepaymentDetailRequest", description = "还款明细请求信息") 19 | public class RepaymentDetailRequest { 20 | 21 | @ApiModelProperty("投资人用户编码") 22 | private String userNo; 23 | 24 | @ApiModelProperty("向投资人收取的佣金") 25 | private BigDecimal commission; 26 | 27 | @ApiModelProperty("派息") 28 | private BigDecimal dividend; 29 | 30 | @ApiModelProperty("投资人应得本金") 31 | private BigDecimal amount; 32 | 33 | @ApiModelProperty("投资人应得利息") 34 | private BigDecimal interest; 35 | } 36 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/repayment/model/RepaymentPlanDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.repayment.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | import java.time.LocalDateTime; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | @Data 14 | public class RepaymentPlanDTO { 15 | /** 16 | * 主键 17 | */ 18 | private Long id; 19 | 20 | /** 21 | * 发标人用户标识 22 | */ 23 | private Long consumerId; 24 | 25 | /** 26 | * 发标人用户编码 27 | */ 28 | private String userNo; 29 | 30 | /** 31 | * 标的标识 32 | */ 33 | private Long projectId; 34 | 35 | /** 36 | * 标的编码 37 | */ 38 | private String projectNo; 39 | 40 | /** 41 | * 期数 42 | */ 43 | private Integer numberOfPeriods; 44 | 45 | /** 46 | * 还款利息 47 | */ 48 | private BigDecimal interest; 49 | 50 | /** 51 | * 还款本金 52 | */ 53 | private BigDecimal principal; 54 | 55 | /** 56 | * 本息 57 | */ 58 | private BigDecimal amount; 59 | 60 | /** 61 | * 应还时间 62 | */ 63 | private LocalDateTime shouldRepaymentDate; 64 | 65 | /** 66 | * 应还状态0.待还,1.已清完.2.部分还款 67 | */ 68 | private String repaymentStatus; 69 | 70 | /** 71 | * 计划创建时间 72 | */ 73 | private LocalDateTime createDate; 74 | 75 | /** 76 | * 借款人让利 77 | */ 78 | private BigDecimal commission; 79 | } 80 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/repayment/model/RepaymentRequest.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.repayment.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.List; 9 | 10 | /** 11 | *

12 | * 还款信息 13 | *

14 | * 15 | * @author yuelimin 16 | * @since 1.8 17 | */ 18 | @Data 19 | @ApiModel(value = "RepaymentRequest", description = "还款请求信息") 20 | public class RepaymentRequest { 21 | 22 | @ApiModelProperty("请求流水号") 23 | private String requestNo; 24 | 25 | @ApiModelProperty("预处理业务流水号") 26 | private String preRequestNo; 27 | 28 | @ApiModelProperty("标的编码") 29 | private String projectNo; 30 | 31 | @ApiModelProperty("平台佣金 -- 具体金额") 32 | private BigDecimal commission; 33 | 34 | @ApiModelProperty("放款明细") 35 | private List details; 36 | 37 | @ApiModelProperty("业务id") 38 | private Long id; 39 | 40 | @ApiModelProperty("还款总额") 41 | private BigDecimal amount; 42 | } 43 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/search/ContentSearchAPI.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.search; 2 | 3 | import com.wanxin.api.search.model.ProjectQueryParamsDTO; 4 | import com.wanxin.api.transaction.model.ProjectDTO; 5 | import com.wanxin.common.domain.PageVO; 6 | import com.wanxin.common.domain.RestResponse; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | public interface ContentSearchAPI { 14 | /** 15 | * 检索标的 16 | * 17 | * @param projectQueryParamsDTO 18 | * @return 19 | */ 20 | RestResponse> queryProjectIndex(ProjectQueryParamsDTO projectQueryParamsDTO, Integer pageNo, Integer pageSize, String sortBy, String order); 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/search/model/ProjectQueryParamsDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.search.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @Data 15 | @ApiModel(value = "ProjectQueryParamsDTO", description = "标的检索条件") 16 | public class ProjectQueryParamsDTO { 17 | 18 | @ApiModelProperty("标的标识") 19 | private Long id; 20 | 21 | @ApiModelProperty("数据标识列表") 22 | private Long[] ids; 23 | 24 | @ApiModelProperty("标的名称(分词匹配)") 25 | private String name; 26 | 27 | @ApiModelProperty("标的描述(分词匹配)") 28 | private String description; 29 | 30 | @ApiModelProperty("起止标的期限(单位:天)") 31 | private Integer startPeriod; 32 | 33 | @ApiModelProperty("起止标的期限(单位:天)") 34 | private Integer endPeriod; 35 | 36 | @ApiModelProperty("起止年化利率(投资人视图)") 37 | private BigDecimal startAnnualRate; 38 | 39 | @ApiModelProperty("起止年化利率(投资人视图)") 40 | private BigDecimal endAnnualRate; 41 | 42 | @ApiModelProperty("标的状态") 43 | private String projectStatus; 44 | 45 | @ApiModelProperty("可用状态") 46 | private Integer status; 47 | 48 | @ApiModelProperty("是否是债权出让标") 49 | private Integer isAssignment; 50 | } 51 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/DateJsonDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import com.fasterxml.jackson.core.JsonParser; 4 | import com.fasterxml.jackson.core.JsonProcessingException; 5 | import com.fasterxml.jackson.databind.DeserializationContext; 6 | import com.fasterxml.jackson.databind.JsonDeserializer; 7 | 8 | import java.io.IOException; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Date; 11 | 12 | /** 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | public class DateJsonDeserializer extends JsonDeserializer { 18 | @Override 19 | public Date deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException { 20 | try { 21 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 22 | return sdf.parse(parser.getValueAsString()); 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | } 26 | return null; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/ModifyProjectStatusDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | *

7 | * 修改标的状态DTO 8 | *

9 | * 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @Data 15 | public class ModifyProjectStatusDTO { 16 | /** 17 | * 请求流水号 18 | */ 19 | private String requestNo; 20 | /** 21 | * 标的号 22 | */ 23 | private String projectNo; 24 | /** 25 | * 更新标的状态 26 | */ 27 | private String projectStatus; 28 | 29 | /** 30 | * 业务实体id 31 | */ 32 | private Long id; 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/ProjectInvestDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | /** 8 | *

9 | * 投标信息 10 | *

11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Data 17 | @ApiModel(value = "ProjectInvestDTO", description = "用户投标信息") 18 | public class ProjectInvestDTO { 19 | 20 | @ApiModelProperty("标的标识") 21 | private Long id; 22 | 23 | @ApiModelProperty("投标金额") 24 | private String amount; 25 | } 26 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/ProjectQueryDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | 9 | /** 10 | *

11 | * 标的信息查询对象 12 | *

13 | * 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | @Data 19 | @ApiModel(value = "ProjectQueryDTO", description = "标的信息查询对象") 20 | public class ProjectQueryDTO { 21 | 22 | @ApiModelProperty("标的类型") 23 | private String type; 24 | 25 | @ApiModelProperty("名称") 26 | private String name; 27 | 28 | @ApiModelProperty("起止标的期限(单位:天)") 29 | private Integer startPeriod; 30 | 31 | @ApiModelProperty("起止标的期限(单位:天)") 32 | private Integer endPeriod; 33 | 34 | @ApiModelProperty("起止年化利率(投资人视图)") 35 | private BigDecimal startAnnualRate; 36 | 37 | @ApiModelProperty("起止年化利率(投资人视图)") 38 | private BigDecimal endAnnualRate; 39 | 40 | @ApiModelProperty("年化利率(借款人视图)") 41 | private BigDecimal borrowerAnnualRate; 42 | 43 | @ApiModelProperty("还款方式") 44 | private String repaymentWay; 45 | 46 | @ApiModelProperty("标的状态") 47 | private String projectStatus; 48 | 49 | @ApiModelProperty("标的可用状态") 50 | private String status; 51 | 52 | } 53 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/ProjectWithTendersDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.List; 7 | 8 | /** 9 | *

10 | * 标的还款信息 11 | *

12 | * 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | @Data 18 | public class ProjectWithTendersDTO { 19 | /** 20 | * 标的信息 21 | */ 22 | private ProjectDTO project; 23 | 24 | /** 25 | * 标的对应的所有投标记录 26 | */ 27 | private List tenders; 28 | 29 | /** 30 | * 投资人让出利率 (投资人让利) 31 | */ 32 | private BigDecimal commissionInvestorAnnualRate; 33 | 34 | /** 35 | * 借款人给平台的利率 (借款人让利) 36 | */ 37 | private BigDecimal commissionBorrowerAnnualRate; 38 | } 39 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/TenderDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.math.BigDecimal; 6 | import java.util.Date; 7 | 8 | /** 9 | *

10 | * 投标信息表 11 | *

12 | * 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | @Data 18 | public class TenderDTO { 19 | /** 20 | * 主键 21 | */ 22 | private Long id; 23 | 24 | /** 25 | * 投标人用户标识 26 | */ 27 | private Long consumerId; 28 | 29 | /** 30 | * 投标人用户名 31 | */ 32 | private String consumerUsername; 33 | 34 | /** 35 | * 投标人用户编码 36 | */ 37 | private String userNo; 38 | 39 | /** 40 | * 标的标识 41 | */ 42 | private Long projectId; 43 | 44 | /** 45 | * 标的编码 46 | */ 47 | private String projectNo; 48 | 49 | /** 50 | * 投标冻结金额 51 | */ 52 | private BigDecimal amount; 53 | 54 | /** 55 | * 投标状态 56 | */ 57 | private String tenderStatus; 58 | 59 | /** 60 | * 创建时间 61 | */ 62 | // private LocalDateTime createDate; 63 | private Date createDate; 64 | 65 | /** 66 | * 投标/债权转让 请求流水号 67 | */ 68 | private String requestNo; 69 | 70 | /** 71 | * 可用状态 72 | */ 73 | private Integer status; 74 | 75 | /** 76 | * 标的名称 77 | */ 78 | private String projectName; 79 | 80 | /** 81 | * 标的期限(单位:天) -- 冗余字段 82 | */ 83 | private Integer projectPeriod; 84 | 85 | /** 86 | * 年化利率(投资人视图) -- 冗余字段 87 | */ 88 | private BigDecimal projectAnnualRate; 89 | 90 | /** 91 | * 标的信息 92 | */ 93 | private ProjectDTO project; 94 | 95 | /** 96 | * 预期收益 97 | */ 98 | private BigDecimal expectedIncome; 99 | 100 | } 101 | -------------------------------------------------------------------------------- /wanxinp2p-api/src/main/java/com/wanxin/api/transaction/model/TenderOverviewDTO.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.api.transaction.model; 2 | 3 | import io.swagger.annotations.ApiModel; 4 | import io.swagger.annotations.ApiModelProperty; 5 | import lombok.Data; 6 | 7 | import java.math.BigDecimal; 8 | import java.util.Date; 9 | 10 | /** 11 | *

12 | * 投标信息预览 13 | *

14 | * 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | @Data 20 | @ApiModel(value = "TenderOverviewDTO", description = "投标信息预览") 21 | public class TenderOverviewDTO { 22 | 23 | @ApiModelProperty("主键") 24 | private Long id; 25 | 26 | @ApiModelProperty("投标人用户标识") 27 | private Long consumerId; 28 | 29 | @ApiModelProperty("投标人用户名") 30 | private String consumerUsername; 31 | 32 | @ApiModelProperty("投标冻结金额") 33 | private BigDecimal amount; 34 | 35 | @ApiModelProperty("投标方式") 36 | private String tenderWay = "手动出借"; 37 | 38 | @ApiModelProperty("创建时间") 39 | // private LocalDateTime createDate; 40 | private Date createDate; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/BusinessException.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | * @author yuelimin 5 | * @version 1.0.0 6 | * @since 1.8 7 | */ 8 | public class BusinessException extends RuntimeException { 9 | private static final long serialVersionUID = 5565760508056698922L; 10 | 11 | private ErrorCode errorCode; 12 | 13 | public BusinessException(ErrorCode errorCode) { 14 | super(); 15 | this.errorCode = errorCode; 16 | } 17 | 18 | public BusinessException() { 19 | super(); 20 | } 21 | 22 | public BusinessException(String arg0, Throwable arg1, boolean arg2, boolean arg3) { 23 | super(arg0, arg1, arg2, arg3); 24 | } 25 | 26 | public BusinessException(ErrorCode errorCode, String arg0, Throwable arg1, boolean arg2, boolean arg3) { 27 | super(arg0, arg1, arg2, arg3); 28 | this.errorCode = errorCode; 29 | } 30 | 31 | public BusinessException(String arg0, Throwable arg1) { 32 | super(arg0, arg1); 33 | } 34 | 35 | public BusinessException(ErrorCode errorCode, String arg0, Throwable arg1) { 36 | super(arg0, arg1); 37 | this.errorCode = errorCode; 38 | } 39 | 40 | public BusinessException(String arg0) { 41 | super(arg0); 42 | } 43 | 44 | public BusinessException(ErrorCode errorCode, String arg0) { 45 | super(arg0); 46 | this.errorCode = errorCode; 47 | } 48 | 49 | public BusinessException(Throwable arg0) { 50 | super(arg0); 51 | } 52 | 53 | public BusinessException(ErrorCode errorCode, Throwable arg0) { 54 | super(arg0); 55 | this.errorCode = errorCode; 56 | } 57 | 58 | public ErrorCode getErrorCode() { 59 | return errorCode; 60 | } 61 | 62 | public void setErrorCode(ErrorCode errorCode) { 63 | this.errorCode = errorCode; 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/CodePrefixCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | * @author yuelimin 5 | * @version 1.0.0 6 | * @since 1.8 7 | */ 8 | public enum CodePrefixCode { 9 | 10 | /** 11 | * 不使前缀 12 | */ 13 | CODE_NO_PREFIX("", "不使前缀"), 14 | 15 | /** 16 | * 标的号前缀 17 | */ 18 | CODE_PROJECT_PREFIX("PRO_", "标的号前缀"), 19 | 20 | /** 21 | * 用户编码前缀 22 | */ 23 | CODE_CONSUMER_PREFIX("USR_", "用户编码前缀"), 24 | 25 | /** 26 | * 请求流水号前缀 27 | */ 28 | CODE_REQUEST_PREFIX("REQ_", "请求流水号前缀"); 29 | 30 | 31 | private String code; 32 | private String desc; 33 | 34 | CodePrefixCode(String code, String desc) { 35 | this.code = code; 36 | this.desc = desc; 37 | } 38 | 39 | public String getCode() { 40 | return code; 41 | } 42 | 43 | public void setCode(String code) { 44 | this.code = code; 45 | } 46 | 47 | public String getDesc() { 48 | return desc; 49 | } 50 | 51 | public void setDesc(String desc) { 52 | this.desc = desc; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/DepositoryReturnCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | *

5 | * 存管系统返回状态码 6 | *

7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public enum DepositoryReturnCode { 13 | /** 14 | * 成功标记 15 | */ 16 | RETURN_CODE_00000("00000", "成功"), 17 | /** 18 | * 系统异常 19 | */ 20 | RETURN_CODE_00001("00001", "系统异常"), 21 | /** 22 | * 系统内部错误 23 | */ 24 | RETURN_CODE_00002("00002", "系统内部错误"), 25 | /** 26 | * 系统内部错误 27 | */ 28 | RETURN_CODE_00003("00003", "参数校验不通过"), 29 | /** 30 | * 系统内部错误 31 | */ 32 | RETURN_CODE_00004("00004", "签名验证失败"); 33 | 34 | private String code; 35 | private String desc; 36 | 37 | DepositoryReturnCode(String code, String desc) { 38 | this.code = code; 39 | this.desc = desc; 40 | } 41 | 42 | public String getCode() { 43 | return code; 44 | } 45 | 46 | public void setCode(String code) { 47 | this.code = code; 48 | } 49 | 50 | public String getDesc() { 51 | return desc; 52 | } 53 | 54 | public void setDesc(String desc) { 55 | this.desc = desc; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/ErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | * @author yuelimin 5 | * @version 1.0.0 6 | * @since 1.8 7 | */ 8 | public interface ErrorCode { 9 | int getCode(); 10 | 11 | String getDesc(); 12 | } 13 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/PageRequestParams.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | * @author yuelimin 5 | * @version 1.0.0 6 | * @since 1.8 7 | */ 8 | public class PageRequestParams { 9 | 10 | private long startRow; 11 | 12 | private long limit; 13 | 14 | private PageRequestParams(Long startRow, Long limit) { 15 | this.startRow = startRow; 16 | this.limit = limit; 17 | } 18 | 19 | public static PageRequestParams of(Integer pageNo, Integer pageSize) { 20 | Long startRow = Long.valueOf((pageNo - 1) * pageSize); 21 | Long limit = Long.valueOf((pageSize)); 22 | return new PageRequestParams(startRow, limit); 23 | } 24 | 25 | public long getStartRow() { 26 | return startRow; 27 | } 28 | 29 | public void setStartRow(long startRow) { 30 | this.startRow = startRow; 31 | } 32 | 33 | public long getLimit() { 34 | return limit; 35 | } 36 | 37 | public void setLimit(long limit) { 38 | this.limit = limit; 39 | } 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/PreprocessBusinessTypeCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | * @author yuelimin 5 | * @version 1.0.0 6 | * @since 1.8 7 | */ 8 | public enum PreprocessBusinessTypeCode { 9 | /** 10 | * 用户 投标 业务代码 11 | */ 12 | TENDER("TENDER", "投标"), 13 | /** 14 | * 用户 还款 业务代码 15 | */ 16 | REPAYMENT("REPAYMENT", "还款"), 17 | /** 18 | * 用户 债权购买 业务代码 19 | */ 20 | CREDIT_ASSIGNMENT("CREDIT_ASSIGNMENT", "债权购买"), 21 | /** 22 | * 用户 代偿 业务代码 23 | */ 24 | COMPENSATORY("COMPENSATORY", "代偿"), 25 | /** 26 | * 用户 代偿还款 业务代码 27 | */ 28 | COMPENSATORY_REPAYMENT("COMPENSATORY_REPAYMENT", "代偿还款"), 29 | ; 30 | 31 | private String code; 32 | private String desc; 33 | 34 | PreprocessBusinessTypeCode(String code, String desc) { 35 | this.code = code; 36 | this.desc = desc; 37 | } 38 | 39 | public String getCode() { 40 | return code; 41 | } 42 | 43 | public void setCode(String code) { 44 | this.code = code; 45 | } 46 | 47 | public String getDesc() { 48 | return desc; 49 | } 50 | 51 | public void setDesc(String desc) { 52 | this.desc = desc; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/ProjectCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | *

5 | * 标的状态码枚举类 6 | *

7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public enum ProjectCode { 13 | 14 | /** 15 | * 借款人新建发标状态为: 募集中 16 | */ 17 | COLLECTING("COLLECTING", "募集中"), 18 | 19 | /** 20 | * 投资人完成投标状态为: 已满标 21 | */ 22 | FULLY("FULLY", "已满标"), 23 | 24 | /** 25 | * 借款人已开始还款状态为: 还款中 26 | */ 27 | REPAYING("REPAYING", "还款中"), 28 | 29 | /** 30 | * 借款人标的已被投资完成状态为: 已截标 31 | */ 32 | FINISH("FINISH", "已截标"), 33 | 34 | /** 35 | * 借款人标的未投资完成状态为: 流标 36 | */ 37 | MISCARRY("MISCARRY", "流标"); 38 | 39 | private String code; 40 | private String desc; 41 | 42 | ProjectCode(String code, String desc) { 43 | this.code = code; 44 | this.desc = desc; 45 | } 46 | 47 | public String getCode() { 48 | return code; 49 | } 50 | 51 | public void setCode(String code) { 52 | this.code = code; 53 | } 54 | 55 | public String getDesc() { 56 | return desc; 57 | } 58 | 59 | public void setDesc(String desc) { 60 | this.desc = desc; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/RepaymentWayCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | *

5 | * 还款方式 编码 6 | *

7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public enum RepaymentWayCode { 13 | /** 14 | * 一次性还款(含本息) 15 | */ 16 | ALL("ALL", "一次性还款(含本息)"), 17 | 18 | /** 19 | * 先息后本 20 | */ 21 | INTEREST_FIRST("INTEREST_FIRST", "先息后本"), 22 | 23 | /** 24 | * 等额本息 25 | */ 26 | FIXED_REPAYMENT("FIXED_REPAYMENT", "等额本息"), 27 | 28 | /** 29 | * 等额本金 30 | */ 31 | FIXED_CAPITAL("FIXED_CAPITAL", "等额本金"); 32 | 33 | 34 | private String code; 35 | private String desc; 36 | 37 | RepaymentWayCode(String code, String desc) { 38 | this.code = code; 39 | this.desc = desc; 40 | } 41 | 42 | public String getCode() { 43 | return code; 44 | } 45 | 46 | public void setCode(String code) { 47 | this.code = code; 48 | } 49 | 50 | public String getDesc() { 51 | return desc; 52 | } 53 | 54 | public void setDesc(String desc) { 55 | this.desc = desc; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/domain/StatusCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.domain; 2 | 3 | /** 4 | * @author yuelimin 5 | * @version 1.0.0 6 | * @since 1.8 7 | */ 8 | public enum StatusCode { 9 | 10 | /** 11 | * 发/同布失败 12 | */ 13 | STATUS_FAIL(2, "发/同布失败"), 14 | /** 15 | * 已发/同布 16 | */ 17 | STATUS_IN(1, "已发/同布"), 18 | /** 19 | * 未发/同布 20 | */ 21 | STATUS_OUT(0, "未发/同布"); 22 | 23 | private Integer code; 24 | private String desc; 25 | 26 | StatusCode(int code, String desc) { 27 | this.code = code; 28 | this.desc = desc; 29 | } 30 | 31 | public int getCode() { 32 | return code; 33 | } 34 | 35 | public void setCode(int code) { 36 | this.code = code; 37 | } 38 | 39 | public String getDesc() { 40 | return desc; 41 | } 42 | 43 | public void setDesc(String desc) { 44 | this.desc = desc; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/util/CodeNoUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.util; 2 | 3 | import com.wanxin.common.domain.CodePrefixCode; 4 | 5 | import java.util.UUID; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public class CodeNoUtil { 13 | /** 14 | * 使用UUID使用编码 15 | * 16 | * @param prefixCode 前缀用与标识不同业务, 已用枚举类型规定业务名称 17 | * @return java.lang.String 18 | */ 19 | public static String getNo(CodePrefixCode prefixCode) { 20 | 21 | return prefixCode.getCode() + UUID.randomUUID().toString().replaceAll("-", "").toUpperCase(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/util/CommonUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.util; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | /** 6 | * @author yuelimin 7 | * @version 1.0.0 8 | * @since 1.8 9 | */ 10 | public class CommonUtil { 11 | 12 | public static String hiddenMobile(String mobile) { 13 | if (StringUtils.isBlank(mobile)) { 14 | return ""; 15 | } 16 | return mobile.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"); 17 | } 18 | 19 | } 20 | 21 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/util/JsonUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.util; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONException; 5 | import com.alibaba.fastjson.JSONObject; 6 | import com.alibaba.fastjson.serializer.SerializerFeature; 7 | 8 | import java.util.ArrayList; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.Map; 12 | 13 | /** 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | public class JsonUtil { 19 | public static String objectTojson(Object object) { 20 | return JSON.toJSONString(object, SerializerFeature.WriteDateUseDateFormat); 21 | } 22 | 23 | public static String listTojson(List list) { 24 | return JSON.toJSONString(list, SerializerFeature.WriteDateUseDateFormat); 25 | } 26 | 27 | /** 28 | * 字符串Json格式转换为对象Map 29 | * 30 | * @param strJson {"username":"sxb"} 31 | * @return 根据json转换为Map对象 32 | */ 33 | public static Map jsonToMap(String strJson) { 34 | Map jsoMap = new HashMap(); 35 | try { 36 | jsoMap = JSONObject.parseObject(strJson, Map.class); 37 | } catch (JSONException e) { 38 | System.out.println("json转换Map出错: " + e.getMessage()); 39 | } 40 | 41 | return jsoMap; 42 | } 43 | 44 | /** 45 | * 字符串Json 转换为对象List 46 | * 47 | * @param strJson [{"username":"sxb"}] 48 | * @return 根据json转换List 49 | */ 50 | public static List> jsonToList(String strJson) { 51 | List> list = new ArrayList>(); 52 | try { 53 | list = JSONObject.parseObject(strJson, List.class); 54 | } catch (JSONException e) { 55 | System.out.println("json转换List出错: " + e.getMessage()); 56 | } 57 | return list; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/util/MD5Util.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.util; 2 | 3 | import java.security.MessageDigest; 4 | import java.security.NoSuchAlgorithmException; 5 | 6 | /** 7 | * @author yuelimin 8 | * @version 1.0.0 9 | * @since 1.8 10 | */ 11 | public class MD5Util { 12 | /** 13 | * 获取字符串的MD5摘要计算结果 14 | * 15 | * @param plainText 16 | * @return 17 | */ 18 | public static String getMd5(String plainText) { 19 | try { 20 | MessageDigest md = MessageDigest.getInstance("MD5"); 21 | md.update(plainText.getBytes()); 22 | byte b[] = md.digest(); 23 | 24 | int i; 25 | 26 | StringBuffer buf = new StringBuffer(""); 27 | for (int offset = 0; offset < b.length; offset++) { 28 | i = b[offset]; 29 | if (i < 0) { 30 | i += 256; 31 | } 32 | if (i < 16) { 33 | buf.append("0"); 34 | } 35 | buf.append(Integer.toHexString(i)); 36 | } 37 | // 16位的加密 38 | // return buf.toString().substring(8, 24); 39 | 40 | // 32位加密 41 | return buf.toString(); 42 | } catch (NoSuchAlgorithmException e) { 43 | e.printStackTrace(); 44 | return null; 45 | } 46 | 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /wanxinp2p-common/src/main/java/com/wanxin/common/util/OkHttpUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.common.util; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.wanxin.common.domain.CommonErrorCode; 5 | import com.wanxin.common.domain.RestResponse; 6 | import okhttp3.MediaType; 7 | import okhttp3.OkHttpClient; 8 | import okhttp3.Request; 9 | import okhttp3.Response; 10 | 11 | import java.io.IOException; 12 | import java.util.concurrent.TimeUnit; 13 | 14 | /** 15 | * OKHTTP 请求工具类 16 | * 17 | * @author yuelimin 18 | * @version 1.0.0 19 | * @since 1.8 20 | */ 21 | public class OkHttpUtil { 22 | private static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8"); 23 | private static OkHttpClient okHttpClient = new OkHttpClient().newBuilder().retryOnConnectionFailure(true) 24 | .connectTimeout(10, TimeUnit.SECONDS) 25 | .readTimeout(10, TimeUnit.SECONDS) 26 | .writeTimeout(10, TimeUnit.SECONDS).build(); 27 | 28 | /** 29 | * 发送post请求 30 | * 31 | * @param url 32 | * @param json 33 | * @return 34 | */ 35 | public static RestResponse post(String url, String json) { 36 | okhttp3.RequestBody body = okhttp3.RequestBody.create(JSON_TYPE, json); 37 | Request request = new Request.Builder().url(url).post(body).build(); 38 | try (Response response = okHttpClient.newCall(request).execute()) { 39 | okhttp3.ResponseBody responseBody = response.body(); 40 | if (responseBody != null) { 41 | return JSON.parseObject(responseBody.string(), RestResponse.class); 42 | } 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | return RestResponse.validfail(CommonErrorCode.E_100106.getDesc()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/ConsumerServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; 7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 8 | import org.springframework.cloud.openfeign.EnableFeignClients; 9 | import org.springframework.transaction.annotation.EnableTransactionManagement; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @EnableDiscoveryClient 17 | @EnableTransactionManagement 18 | @EnableFeignClients(basePackages = {"com.wanxin.consumer.agent"}) 19 | @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) 20 | public class ConsumerServiceApplication { 21 | public static void main(String[] args) { 22 | SpringApplication.run(ConsumerServiceApplication.class, args); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/agent/AccountApiAgent.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.agent; 2 | 3 | import com.wanxin.api.account.model.AccountDTO; 4 | import com.wanxin.api.account.model.AccountRegisterDTO; 5 | import com.wanxin.common.domain.BusinessException; 6 | import com.wanxin.common.domain.CommonErrorCode; 7 | import com.wanxin.common.domain.RestResponse; 8 | import org.dromara.hmily.annotation.Hmily; 9 | import org.springframework.cloud.openfeign.FeignClient; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestBody; 13 | 14 | /** 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | @FeignClient( 20 | value = "account-service", 21 | fallback = AccountApiAgentFallback.class, 22 | configuration = {AccountApiAgentConfiguration.class}) 23 | public interface AccountApiAgent { 24 | /** 25 | * 用户注册 26 | * 27 | * @param accountRegisterDTO 用户注册信息 28 | * @return 29 | */ 30 | @Hmily 31 | @PostMapping(value = "/account/l/accounts") 32 | RestResponse register(@RequestBody AccountRegisterDTO accountRegisterDTO); 33 | } 34 | 35 | class AccountApiAgentConfiguration { 36 | @Bean 37 | public AccountApiAgentFallback accountApiAgentFallback() { 38 | return new AccountApiAgentFallback(); 39 | } 40 | } 41 | 42 | class AccountApiAgentFallback implements AccountApiAgent { 43 | @Override 44 | public RestResponse register(AccountRegisterDTO accountRegisterDTO) { 45 | throw new BusinessException(CommonErrorCode.E_999995); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/common/ConsumerErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.common; 2 | 3 | import com.wanxin.common.domain.ErrorCode; 4 | 5 | /** 6 | * 异常编码 0成功, -1熔断,-2 标准参数校验不通过,-3会话超时 7 | * 前两位:服务标识 8 | * 中间两位:模块标识 9 | * 后两位:异常标识 10 | * 统一账号服务异常编码 以14开始 11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | public enum ConsumerErrorCode implements ErrorCode { 17 | ////////////////////////////////////c端用户服务异常编码 ////////////////////////// 18 | /** 19 | * 不存在的用户信息 20 | */ 21 | E_140101(140101, "不存在的用户信息"), 22 | E_140102(140102, "请求失败"), 23 | E_140105(140105, "用户已开户"), 24 | E_140106(140106, "注册失败"), 25 | E_140107(140107, "用户已存在"), 26 | E_140108(140108, "身份信息不一致"), 27 | E_140109(140109, "银行卡校验失败"), 28 | E_140110(140110, "身份证校验失败"), 29 | E_140131(140131, "用户充值失败"), 30 | E_140132(140132, "用户存管账户未开通成功"), 31 | E_140141(140141, "用户提现失败"), 32 | E_140151(140151, "银行卡已被绑定"), 33 | E_140161(140161, "百度云ORC获取token失败"), 34 | E_140162(140162, "百度云ORC身份证识别失败"), 35 | ; 36 | 37 | private int code; 38 | private String desc; 39 | 40 | ConsumerErrorCode(int code, String desc) { 41 | this.code = code; 42 | this.desc = desc; 43 | } 44 | 45 | public static ConsumerErrorCode setErrorCode(int code) { 46 | for (ConsumerErrorCode errorCode : ConsumerErrorCode.values()) { 47 | if (errorCode.getCode() == code) { 48 | return errorCode; 49 | } 50 | } 51 | return null; 52 | } 53 | 54 | @Override 55 | public int getCode() { 56 | return code; 57 | } 58 | 59 | @Override 60 | public String getDesc() { 61 | return desc; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/common/SecurityUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.common; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.wanxin.api.account.model.LoginUser; 5 | import com.wanxin.common.util.EncryptUtil; 6 | import org.springframework.web.context.request.RequestContextHolder; 7 | import org.springframework.web.context.request.ServletRequestAttributes; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | public class SecurityUtil { 18 | 19 | /** 20 | * 获取当前登录用户 21 | */ 22 | public static LoginUser getUser() { 23 | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 24 | LoginUser loginUser = new LoginUser(); 25 | if (servletRequestAttributes != null) { 26 | HttpServletRequest request = servletRequestAttributes.getRequest(); 27 | 28 | Map jwt = JSONObject.parseObject(EncryptUtil.decodeBase64(request.getHeader("jsonToken")), Map.class); 29 | if (jwt.get("mobile").toString() != null && !"".equals(jwt.get("mobile").toString())) { 30 | loginUser.setMobile(jwt.get("mobile").toString()); 31 | } 32 | 33 | if (jwt.get("client_id").toString() != null && !"".equals(jwt.get("client_id").toString())) { 34 | loginUser.setClientId(jwt.get("client_id").toString()); 35 | } 36 | } 37 | 38 | return loginUser; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * @author yuelimin 12 | * @version 1.0.0 13 | * @since 1.8 14 | */ 15 | @Configuration 16 | @MapperScan("com.wanxin.consumer.mapper") 17 | public class MybatisPlusConfig { 18 | @Bean 19 | public PaginationInterceptor paginationInterceptor() { 20 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 21 | paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); 22 | return paginationInterceptor; 23 | } 24 | 25 | @Bean 26 | public PerformanceInterceptor performanceInterceptor() { 27 | return new PerformanceInterceptor(); 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Configuration 21 | @EnableSwagger2 22 | @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true") 23 | public class SwaggerConfiguration { 24 | @Bean 25 | public Docket buildDocket() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(buildApiInfo()) 28 | .select() 29 | // 要扫描的API(Controller)基础包 30 | .apis(RequestHandlerSelectors.basePackage("com.wanxin")) 31 | .paths(PathSelectors.any()) 32 | .build(); 33 | } 34 | 35 | private ApiInfo buildApiInfo() { 36 | Contact contact = new Contact("岳立民", "https://github.com/mikuhuyo", "yueliminvc@outlook.com"); 37 | return new ApiInfoBuilder() 38 | .title("万信金融P2P平台-用户服务API文档") 39 | .description("用户服务api") 40 | .contact(contact) 41 | .version("1.0.0").build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/entity/BankCard.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | 11 | /** 12 | *

13 | * 用户绑定银行卡信息 14 | *

15 | * 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Data 21 | @TableName("bank_card") 22 | public class BankCard implements Serializable { 23 | 24 | private static final long serialVersionUID = 1L; 25 | 26 | /** 27 | * 主键 28 | */ 29 | @TableId(value = "ID", type = IdType.AUTO) 30 | private Long id; 31 | 32 | /** 33 | * 用户标识 34 | */ 35 | @TableField("CONSUMER_ID") 36 | private Long consumerId; 37 | 38 | /** 39 | * 银行编码 40 | */ 41 | @TableField("BANK_CODE") 42 | private String bankCode; 43 | 44 | /** 45 | * 银行名称 46 | */ 47 | @TableField("BANK_NAME") 48 | private String bankName; 49 | 50 | /** 51 | * 银行卡号 52 | */ 53 | @TableField("CARD_NUMBER") 54 | private String cardNumber; 55 | 56 | /** 57 | * 银行预留手机号 58 | */ 59 | @TableField("MOBILE") 60 | private String mobile; 61 | 62 | /** 63 | * 可用状态 64 | */ 65 | @TableField("STATUS") 66 | private Integer status; 67 | 68 | } 69 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/entity/ConsumerDetails.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | import java.time.LocalDateTime; 11 | 12 | /** 13 | *

14 | * 用户详细信息表 15 | *

16 | * 17 | * @author yuelimin 18 | * @version 1.0.0 19 | * @since 1.8 20 | */ 21 | @Data 22 | @TableName("consumer_details") 23 | public class ConsumerDetails implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | 27 | /** 28 | * 主键 29 | */ 30 | @TableId(value = "ID", type = IdType.AUTO) 31 | private Long id; 32 | 33 | /** 34 | * 用户标识 35 | */ 36 | @TableField("CONSUMER_ID") 37 | private Long consumerId; 38 | 39 | /** 40 | * 身份证照片面标识 41 | */ 42 | @TableField("ID_CARD_PHOTO") 43 | private String idCardPhoto; 44 | 45 | /** 46 | * 身份证国徽面标识 47 | */ 48 | @TableField("ID_CARD_EMBLEM") 49 | private String idCardEmblem; 50 | 51 | /** 52 | * 住址 53 | */ 54 | @TableField("ADDRESS") 55 | private String address; 56 | 57 | /** 58 | * 企业邮箱 59 | */ 60 | @TableField("ENTERPRISE_MAIL") 61 | private String enterpriseMail; 62 | 63 | /** 64 | * 联系人关系 65 | */ 66 | @TableField("CONTACT_RELATION") 67 | private String contactRelation; 68 | 69 | /** 70 | * 联系人姓名 71 | */ 72 | @TableField("CONTACT_NAME") 73 | private String contactName; 74 | 75 | /** 76 | * 联系人电话 77 | */ 78 | @TableField("CONTACT_MOBILE") 79 | private String contactMobile; 80 | 81 | /** 82 | * 创建时间 83 | */ 84 | @TableField("CREATE_DATE") 85 | private LocalDateTime uploadDate; 86 | 87 | } 88 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/entity/RechargeRecord.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | import java.math.BigDecimal; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | *

15 | * 充值记录表 16 | *

17 | * 18 | * @author yuelimin 19 | * @version 1.0.0 20 | * @since 1.8 21 | */ 22 | @Data 23 | @TableName("recharge_record") 24 | public class RechargeRecord implements Serializable { 25 | 26 | private static final long serialVersionUID = 1L; 27 | 28 | /** 29 | * 主键 30 | */ 31 | @TableId(value = "ID", type = IdType.AUTO) 32 | private Long id; 33 | 34 | /** 35 | * 用户标识 36 | */ 37 | @TableField("CONSUMER_ID") 38 | private Long consumerId; 39 | 40 | /** 41 | * 用户编码,生成唯一,用户在存管系统标识 42 | */ 43 | @TableField("USER_NO") 44 | private String userNo; 45 | 46 | /** 47 | * 金额 48 | */ 49 | @TableField("AMOUNT") 50 | private BigDecimal amount; 51 | 52 | /** 53 | * 触发时间 54 | */ 55 | @TableField("CREATE_DATE") 56 | private LocalDateTime createDate; 57 | 58 | /** 59 | * 请求流水号 60 | */ 61 | @TableField("REQUEST_NO") 62 | private String requestNo; 63 | 64 | /** 65 | * 回调状态 66 | */ 67 | @TableField("CALLBACK_STATUS") 68 | private Integer callbackStatus; 69 | } 70 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/entity/WithdrawRecord.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableField; 5 | import com.baomidou.mybatisplus.annotation.TableId; 6 | import com.baomidou.mybatisplus.annotation.TableName; 7 | import lombok.Data; 8 | 9 | import java.io.Serializable; 10 | import java.math.BigDecimal; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | *

15 | * 提现记录表 16 | *

17 | * 18 | * @author yuelimin 19 | * @version 1.0.0 20 | * @since 1.8 21 | */ 22 | @Data 23 | @TableName("withdraw_record") 24 | public class WithdrawRecord implements Serializable { 25 | 26 | private static final long serialVersionUID = 1L; 27 | 28 | /** 29 | * 主键 30 | */ 31 | @TableId(value = "ID", type = IdType.AUTO) 32 | private Long id; 33 | 34 | /** 35 | * 用户标识 36 | */ 37 | @TableField("CONSUMER_ID") 38 | private Long consumerId; 39 | 40 | /** 41 | * 用户编码,生成唯一,用户在存管系统标识 42 | */ 43 | @TableField("USER_NO") 44 | private String userNo; 45 | 46 | /** 47 | * 金额 48 | */ 49 | @TableField("AMOUNT") 50 | private BigDecimal amount; 51 | 52 | /** 53 | * 平台佣金 54 | */ 55 | @TableField("COMMISSION") 56 | private BigDecimal commission; 57 | 58 | /** 59 | * 触发时间 60 | */ 61 | @TableField("CREATE_DATE") 62 | private LocalDateTime createDate; 63 | 64 | /** 65 | * 请求流水号 66 | */ 67 | @TableField("REQUEST_NO") 68 | private String requestNo; 69 | 70 | /** 71 | * 回调状态 72 | */ 73 | @TableField("CALLBACK_STATUS") 74 | private Integer callbackStatus; 75 | } 76 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/interceptor/TokenInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.interceptor; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.TypeReference; 5 | import com.wanxin.api.account.model.LoginUser; 6 | import com.wanxin.common.util.EncryptUtil; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.web.servlet.HandlerInterceptor; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | /** 14 | * Token拦截处理 15 | * 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | public class TokenInterceptor implements HandlerInterceptor { 21 | @Override 22 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) { 23 | String jsonToken = httpServletRequest.getParameter("jsonToken"); 24 | if (StringUtils.isNotBlank(jsonToken)) { 25 | LoginUser loginUser = JSON.parseObject(EncryptUtil.decodeUTF8StringBase64(jsonToken), new TypeReference() { 26 | }); 27 | httpServletRequest.setAttribute("jsonToken", loginUser); 28 | } 29 | return true; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/BankCardMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.consumer.entity.BankCard; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface BankCardMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/BankCardMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/ConsumerDetailsMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.consumer.entity.ConsumerDetails; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface ConsumerDetailsMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/ConsumerDetailsMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/ConsumerMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.consumer.entity.Consumer; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface ConsumerMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/ConsumerMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/RechargeRecordMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.consumer.entity.RechargeRecord; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface RechargeRecordMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/RechargeRecordMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/WithdrawRecordMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.consumer.entity.WithdrawRecord; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface WithdrawRecordMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/mapper/WithdrawRecordMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/service/BankCardService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.service; 2 | 3 | import com.wanxin.api.consumer.model.BankCardDTO; 4 | 5 | /** 6 | * @author yuelimin 7 | * @version 1.0.0 8 | * @since 1.8 9 | */ 10 | public interface BankCardService { 11 | /** 12 | * 根据用户手机号码获取银行卡信息 13 | * 14 | * @param mobile 用户手机号 15 | * @return 16 | */ 17 | BankCardDTO getByUserMobile(String mobile); 18 | 19 | /** 20 | * 获取银行卡信息 21 | * 22 | * @param consumerId 用户id 23 | * @return 24 | */ 25 | BankCardDTO getByConsumerId(Long consumerId); 26 | 27 | /** 28 | * 获取银行卡信息 29 | * 30 | * @param cardNumber 卡号 31 | * @return 32 | */ 33 | BankCardDTO getByCardNumber(String cardNumber); 34 | } 35 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/service/ConsumerDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.service; 2 | 3 | import com.wanxin.api.consumer.model.ConsumerDetailsDTO; 4 | 5 | /** 6 | * @author yuelimin 7 | * @version 1.0.0 8 | * @since 1.8 9 | */ 10 | public interface ConsumerDetailsService { 11 | void createConsumerDetails(ConsumerDetailsDTO consumerDetailsDTO, String mobile); 12 | } 13 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/utils/ApolloConfigUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.utils; 2 | 3 | import com.ctrip.framework.apollo.Config; 4 | import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; 5 | import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * 本类用于获取配置文件中的配置 10 | * 11 | * @author yuelimin 12 | * @since 1.8 13 | */ 14 | @Service 15 | @EnableApolloConfig 16 | public class ApolloConfigUtil { 17 | @ApolloConfig 18 | private static Config config; 19 | 20 | /** 21 | * 银行存管系统服务地址 22 | * 23 | * @return 24 | */ 25 | public static String getDepositoryUrl() { 26 | return config.getProperty("depository.url", null); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/utils/BaiDuOrcIdCardUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.utils; 2 | 3 | import com.wanxin.common.domain.BusinessException; 4 | import com.wanxin.consumer.common.ConsumerErrorCode; 5 | 6 | import java.net.URLEncoder; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | public class BaiDuOrcIdCardUtil { 14 | private static final String URL = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"; 15 | 16 | public static String idCardBack(byte[] imgData) { 17 | try { 18 | String imgStr = Base64Util.encode(imgData); 19 | String imgParam = URLEncoder.encode(imgStr, "UTF-8"); 20 | 21 | String param = "id_card_side=" + "back" + "&image=" + imgParam; 22 | String accessToken = BaiDuOrcAuthServiceUtil.getAuth(); 23 | 24 | return HttpUtil.post(URL, accessToken, param); 25 | } catch (Exception e) { 26 | throw new BusinessException(ConsumerErrorCode.E_140162); 27 | } 28 | } 29 | 30 | public static String idCardFront(byte[] imgData) { 31 | try { 32 | String imgStr = Base64Util.encode(imgData); 33 | String imgParam = URLEncoder.encode(imgStr, "UTF-8"); 34 | 35 | String param = "id_card_side=" + "front" + "&image=" + imgParam; 36 | String accessToken = BaiDuOrcAuthServiceUtil.getAuth(); 37 | 38 | return HttpUtil.post(URL, accessToken, param); 39 | } catch (Exception e) { 40 | throw new BusinessException(ConsumerErrorCode.E_140162); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/utils/GsonUtils.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.utils; 2 | 3 | import com.google.gson.Gson; 4 | import com.google.gson.GsonBuilder; 5 | import com.google.gson.JsonParseException; 6 | 7 | import java.lang.reflect.Type; 8 | 9 | /** 10 | * Json工具类. 11 | * 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | public class GsonUtils { 16 | private static Gson gson = new GsonBuilder().create(); 17 | 18 | public static String toJson(Object value) { 19 | return gson.toJson(value); 20 | } 21 | 22 | public static T fromJson(String json, Class classOfT) throws JsonParseException { 23 | return gson.fromJson(json, classOfT); 24 | } 25 | 26 | public static T fromJson(String json, Type typeOfT) throws JsonParseException { 27 | return (T) gson.fromJson(json, typeOfT); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/java/com/wanxin/consumer/utils/OkHttpUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.consumer.utils; 2 | 3 | import okhttp3.OkHttpClient; 4 | import okhttp3.Request; 5 | import okhttp3.Response; 6 | 7 | import java.io.IOException; 8 | 9 | /** 10 | * okHttp3请求工具类 11 | * 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | public class OkHttpUtil { 16 | /** 17 | * okHttp 同步 GET 请求 18 | * 19 | * @param url 20 | * @return 21 | */ 22 | public static String doSyncGet(String url) throws IOException { 23 | OkHttpClient okHttpClient = new OkHttpClient(); 24 | Request build = new Request.Builder().url(url).build(); 25 | Response execute = okHttpClient.newCall(build).execute(); 26 | assert execute.body() != null; 27 | return execute.body().string(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | servlet: 3 | multipart: 4 | max-file-size: 3MB 5 | 6 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53050 7 | app: 8 | id: consumer-service 9 | apollo: 10 | meta: http://192.168.158.162:8080 11 | bootstrap: 12 | enabled: true 13 | eagerLoad: 14 | enabled: true 15 | namespaces: application,micro_service.spring-boot-druid,micro_service.spring-boot-http,micro_service.spring-eureka,micro_service.spring-hystrix,micro_service.spring-ribbon,micro_service.spring-boot-redis,micro_service.mybatis-plus,micro_service.spring-rocketmq 16 | 17 | logging: 18 | config: classpath:log4j2-dev.xml 19 | 20 | minio: 21 | appId: '' 22 | accessKey: '' 23 | secretKey: '' 24 | uploadUrl: 'http://127.0.0.1:56090/minio/image' 25 | 26 | baidu: 27 | appId: 123 28 | accessKey: '' 29 | secretKey: '' 30 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53050 3 | 4 | spring: 5 | application: 6 | name: consumer-service 7 | main: 8 | banner-mode: 'off' 9 | allow-bean-definition-overriding: true 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-consumer-service/src/main/resources/hmily.yml: -------------------------------------------------------------------------------- 1 | hmily: 2 | server: 3 | configMode: local 4 | appName: consumer-service 5 | config: 6 | appName: consumer-service 7 | serializer: kryo 8 | contextTransmittalMode: threadLocal 9 | scheduledThreadMax: 4 10 | scheduledRecoveryDelay: 60 11 | scheduledCleanDelay: 60 12 | scheduledPhyDeletedDelay: 600 13 | scheduledInitDelay: 30 14 | recoverDelayTime: 60 15 | cleanDelayTime: 180 16 | limit: 200 17 | retryMax: 10 18 | bufferSize: 8192 19 | consumerThreads: 16 20 | asyncRepository: true 21 | autoSql: true 22 | phyDeleted: true 23 | storeDays: 3 24 | repository: mysql 25 | 26 | repository: 27 | database: 28 | driverClassName: com.mysql.cj.jdbc.Driver 29 | url : jdbc:mysql://192.168.158.164:3306/hmily?useUnicode=true&characterEncoding=utf8 30 | username: root 31 | password: yueliminvc@outlook.com 32 | maxActive: 20 33 | minIdle: 10 34 | connectionTimeout: 30000 35 | idleTimeout: 600000 36 | maxLifetime: 1800000 37 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/java/com/wanxin/search/ContentSearchServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.search; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @SpringBootApplication 13 | @EnableDiscoveryClient 14 | public class ContentSearchServiceApplication { 15 | public static void main(String[] args) { 16 | SpringApplication.run(ContentSearchServiceApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/java/com/wanxin/search/common/constant/ContentSearchErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.search.common.constant; 2 | 3 | import com.wanxin.common.domain.ErrorCode; 4 | 5 | /** 6 | * 异常编码: 0成功, -1熔断, -2标准参数校验不通过, -3会话超时 7 | * 前两位: 服务标识 8 | * 中间两位: 模块标识 9 | * 后两位: 异常标识 10 | * 以19开始 11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | public enum ContentSearchErrorCode implements ErrorCode { 17 | /** 18 | * 不存在的用户信息 19 | */ 20 | E_190102(190102, "请求失败"), 21 | ; 22 | 23 | private int code; 24 | private String desc; 25 | 26 | private ContentSearchErrorCode(int code, String desc) { 27 | this.code = code; 28 | this.desc = desc; 29 | } 30 | 31 | public static ContentSearchErrorCode setErrorCode(int code) { 32 | for (ContentSearchErrorCode errorCode : ContentSearchErrorCode.values()) { 33 | if (errorCode.getCode() == code) { 34 | return errorCode; 35 | } 36 | } 37 | return null; 38 | } 39 | 40 | @Override 41 | public int getCode() { 42 | return code; 43 | } 44 | 45 | @Override 46 | public String getDesc() { 47 | return desc; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/java/com/wanxin/search/config/ElasticsearchConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.search.config; 2 | 3 | import org.apache.http.HttpHost; 4 | import org.elasticsearch.client.RestClient; 5 | import org.elasticsearch.client.RestHighLevelClient; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * @author yuelimin 12 | * @version 1.0.0 13 | * @since 1.8 14 | */ 15 | @Configuration 16 | public class ElasticsearchConfig { 17 | @Value("${wanxinp2p.es.host}") 18 | private String es_host; 19 | 20 | @Bean 21 | public RestHighLevelClient restHighLevelClient() { 22 | // 创建RestHighLevelClient客户端 23 | String ip = es_host.split(":")[0]; 24 | int port = Integer.parseInt(es_host.split(":")[1]); 25 | HttpHost httpHost = new HttpHost(ip, port); 26 | return new RestHighLevelClient(RestClient.builder(httpHost)); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/java/com/wanxin/search/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.search.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Configuration 21 | @EnableSwagger2 22 | @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true") 23 | public class SwaggerConfiguration { 24 | @Bean 25 | public Docket buildDocket() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(buildApiInfo()) 28 | .select() 29 | // 要扫描的API(Controller)基础包 30 | .apis(RequestHandlerSelectors.basePackage("com.wanxin")) 31 | .paths(PathSelectors.any()) 32 | .build(); 33 | } 34 | 35 | private ApiInfo buildApiInfo() { 36 | Contact contact = new Contact("岳立民", "https://github.com/mikuhuyo", "yueliminvc@outlook.com"); 37 | return new ApiInfoBuilder() 38 | .title("万信金融P2P平台-内容检索API文档") 39 | .description("内容检索api") 40 | .contact(contact) 41 | .version("1.0.0").build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/java/com/wanxin/search/config/WebMvcConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.search.config; 2 | 3 | import org.springframework.context.annotation.Configuration; 4 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Configuration 13 | public class WebMvcConfiguration implements WebMvcConfigurer { 14 | /** 15 | * 添加静态资源文件, 外部可以直接访问地址 16 | * 17 | * @param registry 18 | */ 19 | @Override 20 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 21 | registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); 22 | 23 | // 解决swagger无法访问 24 | registry 25 | .addResourceHandler("/swagger-ui.html") 26 | .addResourceLocations("classpath:/META-INF/resources/"); 27 | // 解决swagger的js文件无法访问 28 | registry 29 | .addResourceHandler("/webjars/**") 30 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 31 | registry 32 | .addResourceHandler("doc.html") 33 | .addResourceLocations("classpath:/META-INF/resources/"); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/java/com/wanxin/search/service/ContentSearchService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.search.service; 2 | 3 | import com.wanxin.api.search.model.ProjectQueryParamsDTO; 4 | import com.wanxin.api.transaction.model.ProjectDTO; 5 | import com.wanxin.common.domain.PageVO; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public interface ContentSearchService { 13 | /** 14 | * 标的检索 15 | * 16 | * @param queryParamsDTO 查询集 17 | * @param pageNo 页码 18 | * @param pageSize 数据条数 19 | * @param sortBy 排序 20 | * @param order 顺序 21 | * @return 22 | */ 23 | PageVO queryProjectIndex(ProjectQueryParamsDTO queryParamsDTO, Integer pageNo, Integer pageSize, String sortBy, String order); 24 | } 25 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53090 2 | app: 3 | id: content-search-service 4 | apollo: 5 | meta: http://192.168.158.162:8080 6 | bootstrap: 7 | enabled: true 8 | eagerLoad: 9 | enabled: true 10 | namespaces: application,micro_service.spring-boot-http,micro_service.spring-boot-es,micro_service.spring-eureka,micro_service.spring-ribbon,micro_service.spring-feign 11 | 12 | logging: 13 | config: classpath:log4j2-dev.xml 14 | -------------------------------------------------------------------------------- /wanxinp2p-content-search-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53090 3 | 4 | spring: 5 | application: 6 | name: content-search-service 7 | main: 8 | banner-mode: 'off' 9 | allow-bean-definition-overriding: true 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/DepositoryAgentServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; 7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 8 | import org.springframework.transaction.annotation.EnableTransactionManagement; 9 | 10 | /** 11 | * @author yuelimin 12 | * @version 1.0.0 13 | * @since 1.8 14 | */ 15 | @EnableDiscoveryClient 16 | @EnableTransactionManagement 17 | @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) 18 | public class DepositoryAgentServiceApplication { 19 | public static void main(String[] args) { 20 | SpringApplication.run(DepositoryAgentServiceApplication.class, args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/common/constant/DepositoryErrorCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.common.constant; 2 | 3 | import com.wanxin.common.domain.ErrorCode; 4 | 5 | /** 6 | * 存管代理服务异常编码 16 7 | * 8 | * @author yuelimin 9 | * @since 1.8 10 | */ 11 | public enum DepositoryErrorCode implements ErrorCode { 12 | //////////////////////////////////// 交易中心异常编码 16 ////////////////////////// 13 | /** 14 | * 存管代理服务校验存管系统返回数据签名失败 15 | */ 16 | E_160101(160101, "存管代理服务校验存管系统返回数据签名失败"), 17 | E_160102(160102, "交易记录已存在"), 18 | E_160103(160103, "交易正在执行"); 19 | 20 | private int code; 21 | private String desc; 22 | 23 | private DepositoryErrorCode(int code, String desc) { 24 | this.code = code; 25 | this.desc = desc; 26 | } 27 | 28 | public static DepositoryErrorCode setErrorCode(int code) { 29 | for (DepositoryErrorCode errorCode : DepositoryErrorCode.values()) { 30 | if (errorCode.getCode() == code) { 31 | return errorCode; 32 | } 33 | } 34 | return null; 35 | } 36 | 37 | @Override 38 | public int getCode() { 39 | return code; 40 | } 41 | 42 | @Override 43 | public String getDesc() { 44 | return desc; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/common/constant/DepositoryRequestTypeCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.common.constant; 2 | 3 | /** 4 | *

5 | * 银行存管系统请求类型枚举 6 | *

7 | * 8 | * @author yuelimin 9 | * @since 1.8 10 | */ 11 | public enum DepositoryRequestTypeCode { 12 | /** 13 | * 新增标的 14 | */ 15 | CREATE("CREATE", "新增标的"), 16 | /** 17 | * 用户投标 18 | */ 19 | TRADING("TRADING", "用户投标"), 20 | /** 21 | * 审核标满放款 22 | */ 23 | FULL_LOAN("FULL_LOAN", "审核标满放款"), 24 | /** 25 | * 修改标的状态 26 | */ 27 | MODIFY_STATUS("MODIFY_STATUS", "修改标的状态"), 28 | 29 | CONSUMER_CREATE("CONSUMER_CREATE", "开户"), 30 | RECHARGE("RECHARGE", "充值"), 31 | WITHDRAW("WITHDRAW", "提现"); 32 | 33 | private String code; 34 | private String desc; 35 | 36 | DepositoryRequestTypeCode(String code, String desc) { 37 | this.code = code; 38 | this.desc = desc; 39 | } 40 | 41 | public String getCode() { 42 | return code; 43 | } 44 | 45 | public void setCode(String code) { 46 | this.code = code; 47 | } 48 | 49 | public String getDesc() { 50 | return desc; 51 | } 52 | 53 | public void setDesc(String desc) { 54 | this.desc = desc; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | *

12 | * Mybatis-Plus 配置 13 | *

14 | * 15 | * @author yuelimin 16 | * @since 1.8 17 | */ 18 | @Configuration 19 | @MapperScan("com.wanxin.**.mapper") 20 | public class MybatisPlusConfig { 21 | @Bean 22 | public PaginationInterceptor paginationInterceptor() { 23 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 24 | paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); 25 | return paginationInterceptor; 26 | } 27 | 28 | @Bean 29 | public PerformanceInterceptor performanceInterceptor() { 30 | return new PerformanceInterceptor(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.config; 2 | 3 | import com.wanxin.common.cache.Cache; 4 | import com.wanxin.depository.common.cache.RedisCache; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.redis.core.StringRedisTemplate; 8 | 9 | /** 10 | * @author yuelimin 11 | * @since 1.8 12 | */ 13 | @Configuration 14 | public class RedisConfig { 15 | @Bean 16 | public Cache cache(StringRedisTemplate redisTemplate) { 17 | return new RedisCache(redisTemplate); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Configuration 21 | @EnableSwagger2 22 | @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true") 23 | public class SwaggerConfiguration { 24 | @Bean 25 | public Docket buildDocket() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(buildApiInfo()) 28 | .select() 29 | // 要扫描的API(Controller)基础包 30 | .apis(RequestHandlerSelectors.basePackage("com.wanxin")) 31 | .paths(PathSelectors.any()) 32 | .build(); 33 | } 34 | 35 | private ApiInfo buildApiInfo() { 36 | Contact contact = new Contact("岳立民", "https://github.com/mikuhuyo", "yueliminvc@outlook.com"); 37 | return new ApiInfoBuilder() 38 | .title("万信金融P2P平台-银行存管代理API文档") 39 | .description("银行存管代理api") 40 | .contact(contact) 41 | .version("1.0.0").build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.config; 2 | 3 | import com.wanxin.depository.interceptor.DepositoryNotifyVerificationInterceptor; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 6 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | import javax.annotation.Resource; 10 | 11 | /** 12 | * @author yuelimin 13 | * @since 1.8 14 | */ 15 | @Configuration 16 | public class WebConfig implements WebMvcConfigurer { 17 | @Resource 18 | private DepositoryNotifyVerificationInterceptor notifyVerificationInterceptor; 19 | 20 | @Override 21 | public void addInterceptors(InterceptorRegistry registry) { 22 | registry.addInterceptor(notifyVerificationInterceptor).addPathPatterns("/gateway/**"); 23 | } 24 | 25 | /** 26 | * 添加静态资源文件, 外部可以直接访问地址 27 | * 28 | * @param registry 29 | */ 30 | @Override 31 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 32 | registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); 33 | 34 | // 解决swagger无法访问 35 | registry 36 | .addResourceHandler("/swagger-ui.html") 37 | .addResourceLocations("classpath:/META-INF/resources/"); 38 | // 解决swagger的js文件无法访问 39 | registry 40 | .addResourceHandler("/webjars/**") 41 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 42 | registry 43 | .addResourceHandler("doc.html") 44 | .addResourceLocations("classpath:/META-INF/resources/"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/mapper/DepositoryRecordMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.depository.entity.DepositoryRecord; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * 存管交易记录表 Mapper 接口 9 | * 10 | * @author yuelimin 11 | * @since 1.8 12 | */ 13 | @Repository 14 | public interface DepositoryRecordMapper extends BaseMapper { 15 | } 16 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/mapper/DepositoryRecordMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/message/GatewayMessageProducer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.message; 2 | 3 | import com.wanxin.api.depository.model.DepositoryConsumerResponse; 4 | import com.wanxin.api.depository.model.DepositoryRechargeResponse; 5 | import com.wanxin.api.depository.model.DepositoryWithdrawResponse; 6 | import org.apache.rocketmq.spring.core.RocketMQTemplate; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Component; 9 | 10 | /** 11 | *

12 | * 存管代理服务异步通知消息生产者 13 | *

14 | * 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | @Component 20 | public class GatewayMessageProducer { 21 | @Autowired 22 | private RocketMQTemplate template; 23 | 24 | public void personalWithdraw(DepositoryWithdrawResponse response) { 25 | template.convertAndSend("TP_GATEWAY_NOTIFY_AGENT:WITHDRAW", response); 26 | } 27 | 28 | public void personalRecharge(DepositoryRechargeResponse response) { 29 | template.convertAndSend("TP_GATEWAY_NOTIFY_AGENT:RECHARGE", response); 30 | } 31 | 32 | public void personalRegister(DepositoryConsumerResponse response) { 33 | template.convertAndSend("TP_GATEWAY_NOTIFY_AGENT:PERSONAL_REGISTER", response); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/service/ConfigService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.service; 2 | 3 | import com.ctrip.framework.apollo.Config; 4 | import com.ctrip.framework.apollo.spring.annotation.ApolloConfig; 5 | import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig; 6 | import org.springframework.stereotype.Service; 7 | 8 | /** 9 | * 本类用于获取配置文件中的配置, 封装成service方便调用 10 | * 11 | * @author yuelimin 12 | * @since 1.8 13 | */ 14 | @Service 15 | @EnableApolloConfig 16 | public class ConfigService { 17 | @ApolloConfig 18 | private Config config; 19 | 20 | 21 | /** 22 | * 银行存管系统服务地址 23 | * 24 | * @return 25 | */ 26 | public String getDepositoryUrl() { 27 | return config.getProperty("depository.url", null); 28 | } 29 | 30 | /** 31 | * 银行存管系统公钥 32 | * 33 | * @return 34 | */ 35 | public String getDepositoryPublicKey() { 36 | return config.getProperty("depository.publicKey", null); 37 | } 38 | 39 | /** 40 | * 万信P2P系统公钥 41 | * 42 | * @return 43 | */ 44 | public String getP2pPublicKey() { 45 | return config.getProperty("p2p.publicKey", null); 46 | } 47 | 48 | /** 49 | * 万信P2P系统 标识 50 | * 51 | * @return 52 | */ 53 | public String getP2pCode() { 54 | return config.getProperty("p2p.code", null); 55 | } 56 | 57 | /** 58 | * 万信P2P系统私钥 59 | * 60 | * @return 61 | */ 62 | public String getP2pPrivateKey() { 63 | return config.getProperty("p2p.privateKey", null); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/java/com/wanxin/depository/service/OkHttpService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.depository.service; 2 | 3 | import com.wanxin.depository.interceptor.SignatureInterceptor; 4 | import lombok.extern.slf4j.Slf4j; 5 | import okhttp3.OkHttpClient; 6 | import okhttp3.Request; 7 | import okhttp3.Response; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.io.IOException; 12 | 13 | /** 14 | * okHttp3请求工具类 15 | * 16 | * @author yuelimin 17 | * @since 1.8 18 | */ 19 | @Slf4j 20 | @Service 21 | public class OkHttpService { 22 | 23 | @Autowired 24 | private SignatureInterceptor signatureInterceptor; 25 | 26 | /** 27 | * okHttp 同步 GET 请求 28 | * 29 | * @param url 30 | * @return 31 | */ 32 | public String doSyncGet(String url) { 33 | OkHttpClient okHttpClient = new OkHttpClient().newBuilder().addInterceptor(signatureInterceptor).build(); 34 | Request request = new Request.Builder().url(url).build(); 35 | try (Response response = okHttpClient.newCall(request).execute()) { 36 | // 断言 37 | assert response.body() != null; 38 | return response.body().string(); 39 | } catch (IOException e) { 40 | log.warn("请求出现异常: ", e); 41 | } 42 | return ""; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53070 2 | app: 3 | id: depository-agent-service 4 | apollo: 5 | meta: http://192.168.158.162:8080 6 | bootstrap: 7 | enabled: true 8 | eagerLoad: 9 | enabled: true 10 | namespaces: application,micro_service.spring-boot-druid,micro_service.spring-boot-http,micro_service.spring-eureka,micro_service.spring-hystrix,micro_service.spring-feign,micro_service.spring-ribbon,micro_service.mybatis-plus,micro_service.spring-rocketmq,micro_service.spring-boot-redis 11 | 12 | logging: 13 | config: classpath:log4j2-dev.xml 14 | -------------------------------------------------------------------------------- /wanxinp2p-depository-agent-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53070 3 | 4 | spring: 5 | application: 6 | name: depository-agent-service 7 | main: 8 | banner-mode: 'off' 9 | allow-bean-definition-overriding: true 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-discover-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | wanxin-p2p 7 | com.wanxin 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | wanxinp2p-discover-server 13 | 14 | 15 | 16 | org.springframework.cloud 17 | spring-cloud-starter-netflix-eureka-server 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-actuator 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-logging 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-log4j2 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /wanxinp2p-discover-server/src/main/java/com/wanxin/discover/DiscoverServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.discover; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @EnableEurekaServer 13 | @SpringBootApplication 14 | public class DiscoverServerApplication { 15 | public static void main(String[] args) { 16 | SpringApplication.run(DiscoverServerApplication.class, args); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /wanxinp2p-discover-server/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53000 2 | eureka: 3 | server: 4 | # 关闭服务器自我保护,客户端心跳检测15分钟内错误达到80%服务会保护,导致别人还认为是好用的服务 5 | enable-self-preservation: false 6 | # 清理间隔(单位毫秒,默认是60*1000)5秒将客户端剔除的服务在服务注册列表中剔除# 7 | eviction-interval-timer-in-ms: 10000 8 | # eureka是CAP理论种基于AP策略,为了保证强一致性关闭此切换CP 默认不关闭 false关闭 9 | # shouldUseReadOnlyResponseCache: true 10 | client: 11 | # false:不作为一个客户端注册到注册中心 12 | register-with-eureka: false 13 | # 为true时,可以启动,但报异常:Cannot execute request on any known server 14 | fetch-registry: false 15 | serviceUrl: 16 | defaultZone: http://127.0.0.1:${server.port}/eureka/ 17 | instance: 18 | hostname: ${spring.cloud.client.ip-address} 19 | # 注册时使用IP地址,而不是服务名 20 | prefer-ip-address: true 21 | 22 | # 日志配置 23 | logging: 24 | config: classpath:log4j2-dev.xml 25 | -------------------------------------------------------------------------------- /wanxinp2p-discover-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | # 启动端口 2 | server: 3 | port: 53000 4 | 5 | # 应用程序名称 6 | spring: 7 | application: 8 | name: hnradio-discovery 9 | main: 10 | banner-mode: 'off' 11 | allow-bean-definition-overriding: true 12 | profiles: 13 | active: dev 14 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/java/com/wanxin/gateway/GatewayServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.gateway; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.netflix.zuul.EnableZuulProxy; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | @EnableZuulProxy 14 | @EnableDiscoveryClient 15 | @SpringBootApplication 16 | public class GatewayServerApplication { 17 | public static void main(String[] args) { 18 | SpringApplication.run(GatewayServerApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/java/com/wanxin/gateway/common/util/HttpUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.gateway.common.util; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.wanxin.common.domain.RestResponse; 5 | 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | public class HttpUtil { 15 | public static void writerError(RestResponse restResponse, HttpServletResponse response) throws IOException { 16 | response.setContentType("application/json,charset=utf-8"); 17 | response.setStatus(restResponse.getCode()); 18 | ObjectMapper objectMapper = new ObjectMapper(); 19 | objectMapper.writeValue(response.getOutputStream(), restResponse); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/java/com/wanxin/gateway/config/JWTConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.gateway.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.security.oauth2.provider.token.TokenStore; 6 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; 7 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @Configuration 15 | public class JWTConfig { 16 | 17 | private String SIGNING_KEY = "wanxin123"; 18 | 19 | @Bean 20 | public TokenStore tokenStore() { 21 | return new JwtTokenStore(accessTokenConverter()); 22 | } 23 | 24 | @Bean 25 | public JwtAccessTokenConverter accessTokenConverter() { 26 | JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 27 | // 对称秘钥, 资源服务器使用该秘钥来解密 28 | converter.setSigningKey(SIGNING_KEY); 29 | converter.setAccessTokenConverter(new ClientDefaultAccessTokenConverter()); 30 | return converter; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/java/com/wanxin/gateway/config/RestAccessDeniedHandler.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.gateway.config; 2 | 3 | import com.wanxin.common.domain.RestResponse; 4 | import com.wanxin.gateway.common.util.HttpUtil; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.security.access.AccessDeniedException; 7 | import org.springframework.security.web.access.AccessDeniedHandler; 8 | 9 | import javax.servlet.ServletException; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.IOException; 13 | 14 | /** 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | public class RestAccessDeniedHandler implements AccessDeniedHandler { 20 | @Override 21 | public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException ex) throws IOException, ServletException { 22 | RestResponse restResponse = new RestResponse(HttpStatus.FORBIDDEN.value(), "没有权限"); 23 | HttpUtil.writerError(restResponse, response); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/java/com/wanxin/gateway/config/RestOAuth2AuthExceptionEntryPoint.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.gateway.config; 2 | 3 | import com.wanxin.common.domain.RestResponse; 4 | import com.wanxin.gateway.common.util.HttpUtil; 5 | import org.springframework.http.HttpStatus; 6 | import org.springframework.security.core.AuthenticationException; 7 | import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint; 8 | 9 | import javax.servlet.ServletException; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.IOException; 13 | 14 | /** 15 | * @author yuelimin 16 | * @version 1.0.0 17 | * @since 1.8 18 | */ 19 | public class RestOAuth2AuthExceptionEntryPoint extends OAuth2AuthenticationEntryPoint { 20 | @Override 21 | public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { 22 | RestResponse restResponse = new RestResponse(HttpStatus.UNAUTHORIZED.value(), e.getMessage()); 23 | HttpUtil.writerError(restResponse, response); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/java/com/wanxin/gateway/config/ZuulConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.gateway.config; 2 | 3 | import org.springframework.boot.web.servlet.FilterRegistrationBean; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.core.Ordered; 7 | import org.springframework.web.cors.CorsConfiguration; 8 | import org.springframework.web.cors.UrlBasedCorsConfigurationSource; 9 | import org.springframework.web.filter.CorsFilter; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Configuration 17 | public class ZuulConfig { 18 | @Bean 19 | public FilterRegistrationBean corsFilter() { 20 | final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); 21 | final CorsConfiguration config = new CorsConfiguration(); 22 | config.setAllowCredentials(true); 23 | config.addAllowedOrigin("*"); 24 | config.addAllowedHeader("*"); 25 | config.addAllowedMethod("*"); 26 | config.setMaxAge(18000L); 27 | source.registerCorsConfiguration("/**", config); 28 | CorsFilter corsFilter = new CorsFilter(source); 29 | FilterRegistrationBean bean = new FilterRegistrationBean(corsFilter); 30 | bean.setOrder(Ordered.HIGHEST_PRECEDENCE); 31 | return bean; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53010 2 | app: 3 | id: gateway-server 4 | apollo: 5 | meta: http://192.168.158.162:8080 6 | bootstrap: 7 | enabled: true 8 | eagerLoad: 9 | enabled: true 10 | namespaces: application,micro_service.spring-boot-http,micro_service.spring-eureka,micro_service.spring-hystrix,micro_service.spring-ribbon,micro_service.spring-boot-redis 11 | 12 | logging: 13 | config: classpath:log4j2-dev.xml 14 | -------------------------------------------------------------------------------- /wanxinp2p-gateway-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53010 3 | 4 | spring: 5 | application: 6 | name: gateway-server 7 | main: 8 | allow-bean-definition-overriding: true 9 | banner-mode: 'off' 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/RepaymentServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; 6 | import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; 7 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 8 | import org.springframework.cloud.openfeign.EnableFeignClients; 9 | 10 | /** 11 | * @author yuelimin 12 | * @version 1.0.0 13 | * @since 1.8 14 | */ 15 | @EnableDiscoveryClient 16 | @EnableFeignClients(basePackages = {"com.wanxin.repayment.agent"}) 17 | @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class}) 18 | public class RepaymentServiceApplication { 19 | public static void main(String[] args) { 20 | SpringApplication.run(RepaymentServiceApplication.class, args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.transaction.annotation.EnableTransactionManagement; 10 | 11 | /** 12 | *

13 | * Mybatis-Plus 配置 14 | *

15 | * 16 | * @author yuelimin 17 | * @since 1.8 18 | */ 19 | @Configuration 20 | @EnableTransactionManagement 21 | @MapperScan("com.wanxin.**.mapper") 22 | public class MybatisPlusConfig { 23 | @Bean 24 | public PaginationInterceptor paginationInterceptor() { 25 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 26 | paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); 27 | return paginationInterceptor; 28 | } 29 | 30 | @Bean 31 | public PerformanceInterceptor performanceInterceptor() { 32 | return new PerformanceInterceptor(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/config/SchedulerConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.scheduling.TaskScheduler; 6 | import org.springframework.scheduling.annotation.EnableScheduling; 7 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @Configuration 15 | @EnableScheduling 16 | public class SchedulerConfig { 17 | @Bean 18 | public TaskScheduler taskScheduler() { 19 | ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); 20 | // 线程池大小 21 | scheduler.setPoolSize(2); 22 | // 线程名字前缀 23 | scheduler.setThreadNamePrefix("spring-task-thread"); 24 | return scheduler; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Configuration 21 | @EnableSwagger2 22 | @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true") 23 | public class SwaggerConfiguration { 24 | @Bean 25 | public Docket buildDocket() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(buildApiInfo()) 28 | .select() 29 | // 要扫描的API(Controller)基础包 30 | .apis(RequestHandlerSelectors.basePackage("com.wanxin")) 31 | .paths(PathSelectors.any()) 32 | .build(); 33 | } 34 | 35 | private ApiInfo buildApiInfo() { 36 | Contact contact = new Contact("岳立民", "https://github.com/mikuhuyo", "yueliminvc@outlook.com"); 37 | return new ApiInfoBuilder() 38 | .title("万信金融P2P平台-还款服务API文档") 39 | .description("还款服务api") 40 | .contact(contact) 41 | .version("1.0.0").build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.config; 2 | 3 | import com.wanxin.repayment.interceptor.TokenInterceptor; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 6 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | 9 | /** 10 | * @author yuelimin 11 | * @since 1.8 12 | */ 13 | @Configuration 14 | public class WebConfig implements WebMvcConfigurer { 15 | /** 16 | * 添加自定义拦截器 17 | * 18 | * @param registry 拦截器注册对象 19 | */ 20 | @Override 21 | public void addInterceptors(InterceptorRegistry registry) { 22 | registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/**"); 23 | } 24 | 25 | /** 26 | * 添加静态资源文件, 外部可以直接访问地址 27 | * 28 | * @param registry 29 | */ 30 | @Override 31 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 32 | registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); 33 | 34 | // 解决swagger无法访问 35 | registry 36 | .addResourceHandler("/swagger-ui.html") 37 | .addResourceLocations("classpath:/META-INF/resources/"); 38 | // 解决swagger的js文件无法访问 39 | registry 40 | .addResourceHandler("/webjars/**") 41 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 42 | registry 43 | .addResourceHandler("doc.html") 44 | .addResourceLocations("classpath:/META-INF/resources/"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/controller/RepaymentController.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.controller; 2 | 3 | import com.wanxin.api.repayment.RepaymentAPI; 4 | import com.wanxin.api.transaction.model.ProjectWithTendersDTO; 5 | import com.wanxin.common.domain.RestResponse; 6 | import com.wanxin.repayment.service.RepaymentService; 7 | import io.swagger.annotations.Api; 8 | import io.swagger.annotations.ApiImplicitParam; 9 | import io.swagger.annotations.ApiOperation; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.web.bind.annotation.PostMapping; 12 | import org.springframework.web.bind.annotation.RequestBody; 13 | import org.springframework.web.bind.annotation.RestController; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @RestController 21 | @Api(value = "还款服务", tags = "repayment") 22 | public class RepaymentController implements RepaymentAPI { 23 | @Autowired 24 | private RepaymentService repaymentService; 25 | 26 | @Override 27 | @PostMapping("/l/start-repayment") 28 | @ApiOperation("启动还款") 29 | @ApiImplicitParam(name = "projectWithTendersDTO", value = "通过id获取标的信息", required = true, dataType = "ProjectWithTendersDTO", paramType = "body") 30 | public RestResponse startRepayment(@RequestBody ProjectWithTendersDTO projectWithTendersDTO) { 31 | return RestResponse.success(repaymentService.startRepayment(projectWithTendersDTO)); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/entity/ReceivableDetail.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.io.Serializable; 10 | import java.math.BigDecimal; 11 | import java.time.LocalDateTime; 12 | 13 | /** 14 | *

15 | * 投资人实收明细 16 | *

17 | * 18 | * @author yuelimin 19 | * @version 1.0.0 20 | * @since 1.8 21 | */ 22 | @Data 23 | @EqualsAndHashCode(callSuper = false) 24 | @Accessors(chain = true) 25 | public class ReceivableDetail implements Serializable { 26 | 27 | private static final long serialVersionUID = 1L; 28 | 29 | /** 30 | * 主键 31 | */ 32 | @TableId("ID") 33 | private Long id; 34 | 35 | /** 36 | * 应收项标识 37 | */ 38 | @TableField("RECEIVABLE_ID") 39 | private Long receivableId; 40 | 41 | /** 42 | * 实收本息 43 | */ 44 | @TableField("AMOUNT") 45 | private BigDecimal amount; 46 | 47 | /** 48 | * 实收时间 49 | */ 50 | @TableField("RECEIVABLE_DATE") 51 | private LocalDateTime receivableDate; 52 | 53 | 54 | } 55 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/entity/RepaymentDetail.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.entity; 2 | 3 | import com.baomidou.mybatisplus.annotation.TableField; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | import com.baomidou.mybatisplus.annotation.TableName; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.experimental.Accessors; 9 | 10 | import java.io.Serializable; 11 | import java.math.BigDecimal; 12 | import java.time.LocalDateTime; 13 | 14 | /** 15 | *

16 | * 借款人还款明细, 针对一个还款计划可多次进行还款 17 | *

18 | * 19 | * @author yuelimin 20 | * @version 1.0.0 21 | * @since 1.8 22 | */ 23 | @Data 24 | @EqualsAndHashCode(callSuper = false) 25 | @Accessors(chain = true) 26 | @TableName("repayment_detail") 27 | public class RepaymentDetail implements Serializable { 28 | 29 | private static final long serialVersionUID = 1L; 30 | 31 | /** 32 | * 主键 33 | */ 34 | @TableId("ID") 35 | private Long id; 36 | 37 | /** 38 | * 还款计划项标识 39 | */ 40 | @TableField("REPAYMENT_PLAN_ID") 41 | private Long repaymentPlanId; 42 | 43 | /** 44 | * 实还本息 45 | */ 46 | @TableField("AMOUNT") 47 | private BigDecimal amount; 48 | 49 | /** 50 | * 实际还款时间 51 | */ 52 | @TableField("REPAYMENT_DATE") 53 | private LocalDateTime repaymentDate; 54 | 55 | /** 56 | * 冻结用户资金请求流水号(用于解冻合并整体还款), 57 | * 有漏洞, 存管不支持单次“确定还款”, 合并多个还款预处理的操作, 折中做法. 58 | */ 59 | @TableField("REQUEST_NO") 60 | private String requestNo; 61 | 62 | /** 63 | * 可用状态 64 | */ 65 | @TableField("STATUS") 66 | private Integer status; 67 | } 68 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/interceptor/TokenInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.interceptor; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.TypeReference; 5 | import com.wanxin.api.account.model.LoginUser; 6 | import com.wanxin.common.util.EncryptUtil; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.web.servlet.HandlerInterceptor; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | /** 14 | * Token拦截处理 15 | * 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | public class TokenInterceptor implements HandlerInterceptor { 21 | @Override 22 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) { 23 | String jsonToken = httpServletRequest.getParameter("jsonToken"); 24 | if (StringUtils.isNotBlank(jsonToken)) { 25 | LoginUser loginUser = JSON.parseObject(EncryptUtil.decodeUTF8StringBase64(jsonToken), new TypeReference() { 26 | }); 27 | httpServletRequest.setAttribute("jsonToken", loginUser); 28 | } 29 | 30 | return true; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/job/RepaymentSimpleJob.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.job; 2 | 3 | import com.wanxin.repayment.service.RepaymentService; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.scheduling.annotation.Scheduled; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.time.LocalDate; 10 | import java.time.format.DateTimeFormatter; 11 | 12 | /** 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | @Slf4j 18 | @Component 19 | public class RepaymentSimpleJob { 20 | @Autowired 21 | private RepaymentService repaymentService; 22 | 23 | @Scheduled(cron = "*/5 * * * * ?") 24 | public void execute() { 25 | // 定时还款任务 26 | repaymentService.selectDueRepayment(LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/ReceivableDetailMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.repayment.entity.ReceivableDetail; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface ReceivableDetailMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/ReceivableDetailMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/ReceivablePlanMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.repayment.entity.ReceivablePlan; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | *

9 | * 投资人应收明细Mapper接口 10 | *

11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Repository 17 | public interface ReceivablePlanMapper extends BaseMapper { 18 | } 19 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/ReceivablePlanMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/RepaymentDetailMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.repayment.entity.RepaymentDetail; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | @Repository 13 | public interface RepaymentDetailMapper extends BaseMapper { 14 | } 15 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/RepaymentDetailMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/RepaymentPlanMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.repayment.entity.RepaymentPlan; 5 | import org.apache.ibatis.annotations.Param; 6 | import org.apache.ibatis.annotations.Select; 7 | import org.springframework.stereotype.Repository; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 借款人还款计划 Mapper 接口 14 | *

15 | * 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Repository 21 | public interface RepaymentPlanMapper extends BaseMapper { 22 | /** 23 | * 查询所有到期的还款计划 24 | * 25 | * @return 26 | */ 27 | @Select("SELECT * FROM repayment_plan WHERE DATE_FORMAT(SHOULD_REPAYMENT_DATE, '%Y-%m-%d') = #{date} AND REPAYMENT_STATUS = '0'") 28 | List selectDueRepayment(@Param("date") String date); 29 | } 30 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/mapper/RepaymentPlanMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/message/ConfirmRepaymentConsumer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.message; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.wanxin.api.repayment.model.RepaymentRequest; 6 | import com.wanxin.repayment.entity.RepaymentPlan; 7 | import com.wanxin.repayment.service.RepaymentService; 8 | import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 9 | import org.apache.rocketmq.spring.core.RocketMQListener; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Component; 12 | 13 | /** 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | @Component 19 | @RocketMQMessageListener(topic = "TP_CONFIRM_REPAYMENT", consumerGroup = "CID_CONFIRM_REPAYMENT") 20 | public class ConfirmRepaymentConsumer implements RocketMQListener { 21 | @Autowired 22 | private RepaymentService repaymentService; 23 | 24 | @Override 25 | public void onMessage(String msg) { 26 | // 解析消息 27 | JSONObject jsonObject = JSON.parseObject(msg); 28 | RepaymentPlan repaymentPlan = JSONObject.parseObject(jsonObject.getString("repaymentPlan"), RepaymentPlan.class); 29 | RepaymentRequest repaymentRequest = JSONObject.parseObject(jsonObject.getString("repaymentRequest"), RepaymentRequest.class); 30 | 31 | // 执行业务 32 | repaymentService.invokeConfirmRepayment(repaymentPlan, repaymentRequest); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/message/RepaymentProducer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.wanxin.api.repayment.model.RepaymentRequest; 5 | import com.wanxin.repayment.entity.RepaymentPlan; 6 | import org.apache.rocketmq.spring.core.RocketMQTemplate; 7 | import org.springframework.messaging.Message; 8 | import org.springframework.messaging.support.MessageBuilder; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.annotation.Resource; 12 | 13 | /** 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | @Component 19 | public class RepaymentProducer { 20 | @Resource 21 | private RocketMQTemplate rocketMQTemplate; 22 | 23 | public void confirmRepayment(RepaymentPlan repaymentPlan, RepaymentRequest repaymentRequest) { 24 | // 构造消息 25 | JSONObject object = new JSONObject(); 26 | object.put("repaymentPlan", repaymentPlan); 27 | object.put("repaymentRequest", repaymentRequest); 28 | Message msg = MessageBuilder.withPayload(object.toJSONString()).build(); 29 | // 发送消息 30 | rocketMQTemplate.sendMessageInTransaction("PID_CONFIRM_REPAYMENT", "TP_CONFIRM_REPAYMENT", msg, null); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/message/StartRepaymentMessageConsumer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.message; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.JSONObject; 5 | import com.wanxin.api.transaction.model.ProjectWithTendersDTO; 6 | import com.wanxin.repayment.service.RepaymentService; 7 | import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; 8 | import org.apache.rocketmq.spring.core.RocketMQListener; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Component; 11 | 12 | /** 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | // @Slf4j 18 | @Component 19 | @RocketMQMessageListener(topic = "TP_START_REPAYMENT", consumerGroup = "CID_START_REPAYMENT") 20 | public class StartRepaymentMessageConsumer implements RocketMQListener { 21 | @Autowired 22 | private RepaymentService repaymentService; 23 | 24 | @Override 25 | public void onMessage(String projectStr) { 26 | // log.info("消息消费-{}", projectStr); 27 | // 解析消息 28 | JSONObject jsonObject = JSON.parseObject(projectStr); 29 | ProjectWithTendersDTO projectWithTendersDTO = JSONObject.parseObject(jsonObject.getString("projectWithTendersDTO"), ProjectWithTendersDTO.class); 30 | // 调用业务层, 执行本地事务 31 | repaymentService.startRepayment(projectWithTendersDTO); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/java/com/wanxin/repayment/service/RepaymentService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.repayment.service; 2 | 3 | import com.wanxin.api.repayment.model.RepaymentPlanDTO; 4 | import com.wanxin.api.repayment.model.RepaymentRequest; 5 | import com.wanxin.api.transaction.model.ProjectWithTendersDTO; 6 | import com.wanxin.repayment.entity.RepaymentDetail; 7 | import com.wanxin.repayment.entity.RepaymentPlan; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | public interface RepaymentService { 17 | /** 18 | * 远程调用确认还款接口 19 | * 20 | * @param repaymentPlan 21 | * @param repaymentRequest 22 | */ 23 | void invokeConfirmRepayment(RepaymentPlan repaymentPlan, RepaymentRequest repaymentRequest); 24 | 25 | /** 26 | * 执行还款 27 | * 28 | * @param date 29 | */ 30 | void executeRepayment(String date); 31 | 32 | /** 33 | * 确认还款处理 34 | * 35 | * @param repaymentPlan 36 | * @param repaymentRequest 37 | * @return 38 | */ 39 | Boolean confirmRepayment(RepaymentPlan repaymentPlan, RepaymentRequest repaymentRequest); 40 | 41 | /** 42 | * 还款预处理-冻结借款人应还金额 43 | * 44 | * @param repaymentPlan 45 | * @param preRequestNo 46 | * @return 47 | */ 48 | Boolean preRepayment(RepaymentPlan repaymentPlan, String preRequestNo); 49 | 50 | /** 51 | * 根据还款计划生成还款明细并保存 52 | * 53 | * @param repaymentPlan 54 | * @return 55 | */ 56 | RepaymentDetail saveRepaymentDetail(RepaymentPlan repaymentPlan); 57 | 58 | /** 59 | * 查询到期还款计划 60 | * 61 | * @param date yyyy-MM-dd 62 | * @return 63 | */ 64 | List selectDueRepayment(String date); 65 | 66 | /** 67 | * 启动还款 68 | * 69 | * @param projectWithTendersDTO 70 | * @return 71 | */ 72 | String startRepayment(ProjectWithTendersDTO projectWithTendersDTO); 73 | } 74 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53080 2 | app: 3 | id: repayment-service 4 | apollo: 5 | meta: http://192.168.158.162:8080 6 | bootstrap: 7 | enabled: true 8 | eagerLoad: 9 | enabled: true 10 | namespaces: micro_service.spring-boot-druid,application,micro_service.spring-boot-http,micro_service.spring-eureka,micro_service.spring-feign,micro_service.spring-ribbon,micro_service.mybatis-plus,micro_service.spring-rocketmq 11 | 12 | logging: 13 | config: classpath:log4j2-dev.xml 14 | -------------------------------------------------------------------------------- /wanxinp2p-repayment-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53080 3 | 4 | spring: 5 | application: 6 | name: repayment-service 7 | main: 8 | banner-mode: 'off' 9 | allow-bean-definition-overriding: true 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/TransactionServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.cloud.openfeign.EnableFeignClients; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @EnableDiscoveryClient 15 | @SpringBootApplication 16 | @EnableConfigurationProperties 17 | @EnableFeignClients(basePackages = {"com.wanxin.transaction.agent"}) 18 | public class TransactionServiceApplication { 19 | public static void main(String[] args) { 20 | SpringApplication.run(TransactionServiceApplication.class, args); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/common/constant/ProjectTypeCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.common.constant; 2 | 3 | /** 4 | *

5 | * 标的 标的类型 枚举类 6 | *

7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public enum ProjectTypeCode { 13 | 14 | /** 15 | * 新增标 16 | */ 17 | TYPE_CODE_NEW("NEW", "新增标"), 18 | /** 19 | * 存量标 20 | */ 21 | TYPE_CODE_STOCK("STOCK", "存量标"); 22 | 23 | private String code; 24 | private String desc; 25 | 26 | ProjectTypeCode(String code, String desc) { 27 | this.code = code; 28 | this.desc = desc; 29 | } 30 | 31 | public String getCode() { 32 | return code; 33 | } 34 | 35 | public void setCode(String code) { 36 | this.code = code; 37 | } 38 | 39 | public String getDesc() { 40 | return desc; 41 | } 42 | 43 | public void setDesc(String desc) { 44 | this.desc = desc; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/common/constant/TradingCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.common.constant; 2 | 3 | /** 4 | *

5 | * 交易状态枚举类 6 | *

7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public enum TradingCode { 13 | /** 14 | * 已冻结 15 | */ 16 | FROZEN("FROZEN", "已冻结"), 17 | /** 18 | * 已放款 19 | */ 20 | LOAN("LOAN", "已放款"), 21 | /** 22 | * 已退款 23 | */ 24 | REFUNDED("REFUNDED", "已退款"); 25 | 26 | 27 | private String code; 28 | private String desc; 29 | 30 | TradingCode(String code, String desc) { 31 | this.code = code; 32 | this.desc = desc; 33 | } 34 | 35 | public String getCode() { 36 | return code; 37 | } 38 | 39 | public void setCode(String code) { 40 | this.code = code; 41 | } 42 | 43 | public String getDesc() { 44 | return desc; 45 | } 46 | 47 | public void setDesc(String desc) { 48 | this.desc = desc; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/common/constant/TradingStatusCode.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.common.constant; 2 | 3 | /** 4 | *

5 | * 交易状态枚举类 6 | *

7 | * 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public enum TradingStatusCode { 13 | /** 14 | * 交易已受理 15 | */ 16 | STATUS_ACCEPT("ACCEPT", "已受理"), 17 | /** 18 | * 交易成功 19 | */ 20 | STATUS_SUCCESS("SUCCESS", "交易成功"), 21 | /** 22 | * 交易失败 23 | */ 24 | STATUS_FAIL("FAIL", "交易失败"), 25 | /** 26 | * 债权出让中 27 | */ 28 | STATUS_ONSALE("ONSALE", "债权出让中"), 29 | /** 30 | * 已结束 31 | */ 32 | STATUS_COMPLETED("COMPLETED", "已结束"), 33 | /** 34 | * 初始状态 35 | */ 36 | STATUS_INIT("INIT", "初始状态"), 37 | /** 38 | * 处理中 39 | */ 40 | STATUS_PROCESSING("PROCESSING", "处理中"), 41 | /** 42 | * 已退款 43 | */ 44 | STATUS_REFUNDED("REFUNDED", "已退款"); 45 | 46 | private String code; 47 | private String desc; 48 | 49 | TradingStatusCode(String code, String desc) { 50 | this.code = code; 51 | this.desc = desc; 52 | } 53 | 54 | public String getCode() { 55 | return code; 56 | } 57 | 58 | public void setCode(String code) { 59 | this.code = code; 60 | } 61 | 62 | public String getDesc() { 63 | return desc; 64 | } 65 | 66 | public void setDesc(String desc) { 67 | this.desc = desc; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/common/utils/IncomeCalcUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.common.utils; 2 | 3 | import java.math.BigDecimal; 4 | 5 | /** 6 | *

7 | * 投资人预期收益计算工具 8 | *

9 | * 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | public class IncomeCalcUtil { 15 | 16 | /** 17 | * 等额本息 投资人收益计算 18 | * 19 | * @param invest 投资金额 20 | * @param yearRate 年利率 21 | * @param month 月数 22 | * @return 总收益 23 | */ 24 | public static BigDecimal getIncomeTotalInterest(BigDecimal invest, BigDecimal yearRate, int month) { 25 | // 计算月利率 26 | double monthRate = yearRate.doubleValue() / 12; 27 | BigDecimal totalInterest = new BigDecimal(0); 28 | // 计算月息并累加 29 | for (int i = 1; i < month + 1; i++) { 30 | BigDecimal multiply = invest.multiply(new BigDecimal(monthRate)); 31 | BigDecimal sub = new BigDecimal(Math.pow(1 + monthRate, month)).subtract(new BigDecimal(Math.pow(1 + monthRate, i - 1))); 32 | BigDecimal monthInterest = multiply.multiply(sub).divide(new BigDecimal(Math.pow(1 + monthRate, month) - 1), 6, BigDecimal.ROUND_DOWN); 33 | monthInterest = monthInterest.setScale(2, BigDecimal.ROUND_DOWN); 34 | totalInterest = totalInterest.add(monthInterest); 35 | } 36 | return totalInterest; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/common/utils/SecurityUtil.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.common.utils; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.wanxin.api.account.model.LoginUser; 5 | import com.wanxin.common.util.EncryptUtil; 6 | import org.springframework.web.context.request.RequestContextHolder; 7 | import org.springframework.web.context.request.ServletRequestAttributes; 8 | 9 | import javax.servlet.http.HttpServletRequest; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | public class SecurityUtil { 18 | 19 | /** 20 | * 获取当前登录用户 21 | */ 22 | public static LoginUser getUser() { 23 | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 24 | LoginUser loginUser = new LoginUser(); 25 | if (servletRequestAttributes != null) { 26 | HttpServletRequest request = servletRequestAttributes.getRequest(); 27 | 28 | Map jwt = JSONObject.parseObject(EncryptUtil.decodeBase64(request.getHeader("jsonToken")), Map.class); 29 | if (jwt.get("mobile").toString() != null && !"".equals(jwt.get("mobile").toString())) { 30 | loginUser.setMobile(jwt.get("mobile").toString()); 31 | } 32 | 33 | if (jwt.get("client_id").toString() != null && !"".equals(jwt.get("client_id").toString())) { 34 | loginUser.setClientId(jwt.get("client_id").toString()); 35 | } 36 | } 37 | 38 | return loginUser; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/config/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.config; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.transaction.annotation.EnableTransactionManagement; 10 | 11 | /** 12 | *

13 | * Mybatis-Plus 配置 14 | *

15 | * 16 | * @author yuelimin 17 | * @since 1.8 18 | */ 19 | @Configuration 20 | @MapperScan("com.wanxin.**.mapper") 21 | @EnableTransactionManagement(proxyTargetClass = true) 22 | public class MybatisPlusConfig { 23 | /** 24 | * 分页插件 25 | * 26 | * @return 27 | */ 28 | @Bean 29 | public PaginationInterceptor paginationInterceptor() { 30 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 31 | paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); 32 | return paginationInterceptor; 33 | } 34 | 35 | /** 36 | * 性能分析插件 37 | * 38 | * @return 39 | */ 40 | @Bean 41 | public PerformanceInterceptor performanceInterceptor() { 42 | return new PerformanceInterceptor(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/config/SwaggerConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.config; 2 | 3 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import springfox.documentation.builders.ApiInfoBuilder; 7 | import springfox.documentation.builders.PathSelectors; 8 | import springfox.documentation.builders.RequestHandlerSelectors; 9 | import springfox.documentation.service.ApiInfo; 10 | import springfox.documentation.service.Contact; 11 | import springfox.documentation.spi.DocumentationType; 12 | import springfox.documentation.spring.web.plugins.Docket; 13 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 14 | 15 | /** 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Configuration 21 | @EnableSwagger2 22 | @ConditionalOnProperty(prefix = "swagger", value = {"enable"}, havingValue = "true") 23 | public class SwaggerConfiguration { 24 | @Bean 25 | public Docket buildDocket() { 26 | return new Docket(DocumentationType.SWAGGER_2) 27 | .apiInfo(buildApiInfo()) 28 | .select() 29 | // 要扫描的API(Controller)基础包 30 | .apis(RequestHandlerSelectors.basePackage("com.wanxin")) 31 | .paths(PathSelectors.any()) 32 | .build(); 33 | } 34 | 35 | private ApiInfo buildApiInfo() { 36 | Contact contact = new Contact("岳立民", "https://github.com/mikuhuyo", "yueliminvc@outlook.com"); 37 | return new ApiInfoBuilder() 38 | .title("万信金融P2P平台-交易服务中心") 39 | .description("交易服务中心api") 40 | .contact(contact) 41 | .version("1.0.0").build(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/interceptor/OpenFeignInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.interceptor; 2 | 3 | import feign.RequestInterceptor; 4 | import feign.RequestTemplate; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.context.request.RequestContextHolder; 8 | import org.springframework.web.context.request.ServletRequestAttributes; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | 12 | /** 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | @Slf4j 18 | @Configuration 19 | public class OpenFeignInterceptor implements RequestInterceptor { 20 | 21 | @Override 22 | public void apply(RequestTemplate requestTemplate) { 23 | 24 | ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 25 | // 注意: RequestContextHolder依赖于 ThreadLocal, 26 | // 所以在hystrix的隔离策略为THREAD, MQ的消费者, 定时任务调用FeignClient时, 此处应为null. 27 | if (attributes == null) { 28 | return; 29 | } 30 | 31 | HttpServletRequest request = attributes.getRequest(); 32 | String jsonToken = request.getHeader("jsonToken"); 33 | if (jsonToken != null) { 34 | requestTemplate.header("jsonToken", jsonToken); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/interceptor/TokenInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.interceptor; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.TypeReference; 5 | import com.wanxin.api.account.model.LoginUser; 6 | import com.wanxin.common.util.EncryptUtil; 7 | import org.apache.commons.lang.StringUtils; 8 | import org.springframework.web.servlet.HandlerInterceptor; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | /** 14 | *

15 | * Token 拦截处理 16 | *

17 | * 18 | * @author yuelimin 19 | * @version 1.0.0 20 | * @since 1.8 21 | */ 22 | public class TokenInterceptor implements HandlerInterceptor { 23 | @Override 24 | public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) { 25 | String jsonToken = httpServletRequest.getParameter("jsonToken"); 26 | if (StringUtils.isNotBlank(jsonToken)) { 27 | LoginUser loginUser = JSON.parseObject(EncryptUtil.decodeUTF8StringBase64(jsonToken), new TypeReference() { 28 | }); 29 | httpServletRequest.setAttribute("jsonToken", loginUser); 30 | } 31 | return true; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/mapper/ProjectMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.transaction.entity.Project; 5 | import org.springframework.stereotype.Repository; 6 | 7 | /** 8 | *

9 | * 标的信息Mapper接口 10 | *

11 | * 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Repository 17 | public interface ProjectMapper extends BaseMapper { 18 | } 19 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/mapper/ProjectMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/mapper/TenderMapper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.wanxin.transaction.entity.Tender; 5 | import org.apache.ibatis.annotations.Select; 6 | import org.springframework.stereotype.Repository; 7 | 8 | import java.math.BigDecimal; 9 | import java.util.List; 10 | 11 | /** 12 | *

13 | * 用于操作投标信息的mapper接口 14 | *

15 | * 16 | * @author yuelimin 17 | * @version 1.0.0 18 | * @since 1.8 19 | */ 20 | @Repository 21 | public interface TenderMapper extends BaseMapper { 22 | /** 23 | * 根据标的id,获取标的已投金额,如果未投返回0.0 24 | * 25 | * @param id 26 | * @return 27 | */ 28 | @Select("SELECT IFNULL(SUM(AMOUNT), 0.0) FROM tender WHERE PROJECT_ID = #{id} AND STATUS = 1") 29 | List selectAmountInvestedByProjectId(Long id); 30 | } 31 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/mapper/TenderMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/java/com/wanxin/transaction/message/TransactionProducer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.transaction.message; 2 | 3 | import com.alibaba.fastjson.JSONObject; 4 | import com.wanxin.api.transaction.model.ProjectWithTendersDTO; 5 | import com.wanxin.transaction.entity.Project; 6 | import org.apache.rocketmq.spring.core.RocketMQTemplate; 7 | import org.springframework.messaging.Message; 8 | import org.springframework.messaging.support.MessageBuilder; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.annotation.Resource; 12 | 13 | /** 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | @Component 19 | public class TransactionProducer { 20 | @Resource 21 | private RocketMQTemplate template; 22 | 23 | public void updateProjectStatusAndStartRepayment(Project project, ProjectWithTendersDTO projectWithTendersDTO) { 24 | // 构造消息 25 | JSONObject object = new JSONObject(); 26 | object.put("project", project); 27 | object.put("projectWithTendersDTO", projectWithTendersDTO); 28 | Message msg = MessageBuilder.withPayload(object.toJSONString()).build(); 29 | // 发送消息 30 | template.sendMessageInTransaction("PID_START_REPAYMENT", "TP_START_REPAYMENT", msg, null); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-transaction-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53060 3 | 4 | spring: 5 | application: 6 | name: transaction-service 7 | main: 8 | banner-mode: 'off' 9 | allow-bean-definition-overriding: true 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/UAAServiceApplication.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 6 | import org.springframework.cloud.openfeign.EnableFeignClients; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | @EnableDiscoveryClient 14 | @SpringBootApplication 15 | @EnableFeignClients(basePackages = {"com.wanxin.uaa.agent"}) 16 | public class UAAServiceApplication { 17 | public static void main(String[] args) { 18 | SpringApplication.run(UAAServiceApplication.class, args); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/agent/AccountApiAgent.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.agent; 2 | 3 | import com.wanxin.api.account.model.AccountDTO; 4 | import com.wanxin.api.account.model.AccountLoginDTO; 5 | import com.wanxin.common.domain.BusinessException; 6 | import com.wanxin.common.domain.CommonErrorCode; 7 | import com.wanxin.common.domain.RestResponse; 8 | import org.springframework.cloud.openfeign.FeignClient; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.web.bind.annotation.PostMapping; 11 | import org.springframework.web.bind.annotation.RequestBody; 12 | 13 | /** 14 | * @author yuelimin 15 | * @version 1.0.0 16 | * @since 1.8 17 | */ 18 | @FeignClient(value = "account-service", 19 | configuration = AccountApiAgentConfig.class, 20 | fallback = AccountApiAgentFallback.class) 21 | public interface AccountApiAgent { 22 | @PostMapping(value = "/account/l/accounts/session") 23 | RestResponse login(@RequestBody AccountLoginDTO accountLoginDTO); 24 | } 25 | 26 | class AccountApiAgentConfig { 27 | @Bean 28 | public AccountApiAgentFallback accountApiAgentFallback() { 29 | return new AccountApiAgentFallback(); 30 | } 31 | } 32 | 33 | class AccountApiAgentFallback implements AccountApiAgent { 34 | @Override 35 | public RestResponse login(AccountLoginDTO accountLoginDTO) { 36 | throw new BusinessException(CommonErrorCode.E_999995); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/common/utils/ApplicationContextHelper.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.common.utils; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | @Component 14 | public class ApplicationContextHelper implements ApplicationContextAware { 15 | private static ApplicationContext applicationContext; 16 | 17 | public ApplicationContextHelper() { 18 | } 19 | 20 | public static Object getBean(String beanName) { 21 | return applicationContext != null ? applicationContext.getBean(beanName) : null; 22 | } 23 | 24 | public static Object getBean(Class clazz) { 25 | return applicationContext != null ? applicationContext.getBean(clazz) : null; 26 | } 27 | 28 | @Override 29 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 30 | ApplicationContextHelper.applicationContext = applicationContext; 31 | } 32 | } 33 | 34 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/common/utils/GuidGenerator.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.common.utils; 2 | 3 | import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; 4 | 5 | import java.util.UUID; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public abstract class GuidGenerator { 13 | 14 | private static RandomValueStringGenerator defaultClientSecretGenerator = new RandomValueStringGenerator(32); 15 | 16 | /** 17 | * private constructor 18 | */ 19 | private GuidGenerator() { 20 | } 21 | 22 | public static String generate() { 23 | return UUID.randomUUID().toString().replaceAll("-", ""); 24 | } 25 | 26 | public static String generateClientSecret() { 27 | return defaultClientSecretGenerator.generate(); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/common/utils/WebUtils.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.common.utils; 2 | 3 | import org.apache.commons.lang.StringUtils; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public class WebUtils { 13 | public static final String UTF_8 = "UTF-8"; 14 | 15 | public static final String VERSION = "2.0.1"; 16 | 17 | private static ThreadLocal ipThreadLocal = new ThreadLocal<>(); 18 | 19 | // private 20 | private WebUtils() { 21 | } 22 | 23 | public static String getIp() { 24 | return ipThreadLocal.get(); 25 | } 26 | 27 | public static void setIp(String ip) { 28 | ipThreadLocal.set(ip); 29 | } 30 | 31 | /** 32 | * Retrieve client ip address 33 | * 34 | * @param request HttpServletRequest 35 | * @return IP 36 | */ 37 | public static String retrieveClientIp(HttpServletRequest request) { 38 | String ip = request.getHeader("x-forwarded-for"); 39 | if (isUnAvailableIp(ip)) { 40 | ip = request.getHeader("Proxy-Client-IP"); 41 | } 42 | if (isUnAvailableIp(ip)) { 43 | ip = request.getHeader("WL-Proxy-Client-IP"); 44 | } 45 | if (isUnAvailableIp(ip)) { 46 | ip = request.getRemoteAddr(); 47 | } 48 | return ip; 49 | } 50 | 51 | private static boolean isUnAvailableIp(String ip) { 52 | return StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/config/JWTConfig.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.config; 2 | 3 | import com.wanxin.uaa.domain.ClientDefaultAccessTokenConverter; 4 | import com.wanxin.uaa.domain.UnifiedUserAuthenticationConverter; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.security.oauth2.provider.token.TokenStore; 8 | import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; 9 | import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | @Configuration 17 | public class JWTConfig { 18 | private String SIGNING_KEY = "wanxin123"; 19 | 20 | @Bean 21 | public TokenStore tokenStore() { 22 | return new JwtTokenStore(accessTokenConverter()); 23 | } 24 | 25 | @Bean 26 | public JwtAccessTokenConverter accessTokenConverter() { 27 | JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); 28 | // 对称秘钥, 资源服务器使用该秘钥来解密 29 | converter.setSigningKey(SIGNING_KEY); 30 | ClientDefaultAccessTokenConverter accessTokenConverter = new ClientDefaultAccessTokenConverter(); 31 | accessTokenConverter.setUserTokenConverter(new UnifiedUserAuthenticationConverter()); 32 | converter.setAccessTokenConverter(accessTokenConverter); 33 | return converter; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/config/OauthUserApprovalHandler.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.config; 2 | 3 | import com.wanxin.uaa.domain.OauthClientDetails; 4 | import com.wanxin.uaa.service.OauthService; 5 | import org.springframework.security.core.Authentication; 6 | import org.springframework.security.oauth2.provider.AuthorizationRequest; 7 | import org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | public class OauthUserApprovalHandler extends TokenStoreUserApprovalHandler { 15 | 16 | private OauthService oauthService; 17 | 18 | public OauthUserApprovalHandler() { 19 | } 20 | 21 | @Override 22 | public boolean isApproved(AuthorizationRequest authorizationRequest, Authentication userAuthentication) { 23 | if (super.isApproved(authorizationRequest, userAuthentication)) { 24 | return true; 25 | } 26 | if (!userAuthentication.isAuthenticated()) { 27 | return false; 28 | } 29 | 30 | OauthClientDetails clientDetails = oauthService.loadOauthClientDetails(authorizationRequest.getClientId()); 31 | return clientDetails != null && clientDetails.trusted(); 32 | 33 | } 34 | 35 | public void setOauthService(OauthService oauthService) { 36 | this.oauthService = oauthService; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/config/RestOAuth2Exception.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.config; 2 | 3 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 4 | import org.springframework.security.oauth2.common.exceptions.OAuth2Exception; 5 | 6 | /** 7 | * @author yuelimin 8 | * @version 1.0.0 9 | * @since 1.8 10 | */ 11 | @JsonSerialize(using = RestOAuthExceptionJacksonSerializer.class) 12 | public class RestOAuth2Exception extends OAuth2Exception { 13 | 14 | public RestOAuth2Exception(String msg, Throwable t) { 15 | super(msg, t); 16 | } 17 | 18 | public RestOAuth2Exception(String msg) { 19 | super(msg); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/config/RestOAuthExceptionJacksonSerializer.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.config; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.databind.SerializerProvider; 5 | import com.fasterxml.jackson.databind.ser.std.StdSerializer; 6 | import org.springframework.web.util.HtmlUtils; 7 | 8 | import java.io.IOException; 9 | import java.util.Map; 10 | 11 | /** 12 | * @author yuelimin 13 | * @version 1.0.0 14 | * @since 1.8 15 | */ 16 | public class RestOAuthExceptionJacksonSerializer extends StdSerializer { 17 | 18 | protected RestOAuthExceptionJacksonSerializer() { 19 | super(RestOAuth2Exception.class); 20 | } 21 | 22 | @Override 23 | public void serialize(RestOAuth2Exception value, JsonGenerator jgen, SerializerProvider serializerProvider) throws IOException { 24 | jgen.writeStartObject(); 25 | jgen.writeObjectField("code", value.getHttpErrorCode()); 26 | String errorMessage = value.getOAuth2ErrorCode(); 27 | if (errorMessage != null) { 28 | errorMessage = HtmlUtils.htmlEscape(errorMessage); 29 | } 30 | jgen.writeStringField("msg", value.getMessage()); 31 | String summary = value.getSummary(); 32 | jgen.writeStringField("result", summary); 33 | 34 | if (value.getAdditionalInformation() != null) { 35 | for (Map.Entry entry : value.getAdditionalInformation().entrySet()) { 36 | String key = entry.getKey(); 37 | String add = entry.getValue(); 38 | jgen.writeStringField(key, add); 39 | } 40 | } 41 | jgen.writeEndObject(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/domain/CustomJdbcClientDetailsService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.domain; 2 | 3 | import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService; 4 | 5 | import javax.sql.DataSource; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public class CustomJdbcClientDetailsService extends JdbcClientDetailsService { 13 | 14 | private static final String SELECT_CLIENT_DETAILS_SQL = "select client_id, client_secret, resource_ids, scope, authorized_grant_types, " + 15 | "web_server_redirect_uri, authorities, access_token_validity, refresh_token_validity, additional_information, autoapprove " + 16 | "from oauth_client_details where client_id = ? and archived = 0 "; 17 | 18 | public CustomJdbcClientDetailsService(DataSource dataSource) { 19 | super(dataSource); 20 | setSelectClientDetailsSql(SELECT_CLIENT_DETAILS_SQL); 21 | } 22 | 23 | 24 | } 25 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/domain/IntegrationWebAuthenticationDetails.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.domain; 2 | 3 | import org.springframework.security.web.authentication.WebAuthenticationDetails; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | /** 8 | * web AuthenticationDetails 自定义, 9 | * 针对web网页用户认证, 10 | * 由于网页端用户认证(认证码模式, 简化模式)会走UsernamePasswordAuthenticationFilter, 11 | * 把request中的额外信息增加至WebAuthenticationDetails. 12 | * 13 | * @author yuelimin 14 | * @version 1.0.0 15 | * @since 1.8 16 | */ 17 | public class IntegrationWebAuthenticationDetails extends WebAuthenticationDetails { 18 | 19 | private final String domain; 20 | 21 | private final String key; 22 | 23 | private final String authenticationType; 24 | 25 | public IntegrationWebAuthenticationDetails(HttpServletRequest request) { 26 | super(request); 27 | domain = request.getParameter("domain"); 28 | key = request.getParameter("key"); 29 | authenticationType = request.getParameter("authenticationType"); 30 | } 31 | 32 | 33 | public String getDomain() { 34 | return domain; 35 | } 36 | 37 | public String getKey() { 38 | return key; 39 | } 40 | 41 | public String getAuthenticationType() { 42 | return authenticationType; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/domain/IntegrationWebAuthenticationDetailsSource.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.domain; 2 | 3 | import org.springframework.security.authentication.AuthenticationDetailsSource; 4 | import org.springframework.security.web.authentication.WebAuthenticationDetails; 5 | import org.springframework.stereotype.Component; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | /** 10 | * @author yuelimin 11 | * @version 1.0.0 12 | * @since 1.8 13 | */ 14 | @Component 15 | public class IntegrationWebAuthenticationDetailsSource implements AuthenticationDetailsSource { 16 | 17 | @Override 18 | public WebAuthenticationDetails buildDetails(HttpServletRequest context) { 19 | return new IntegrationWebAuthenticationDetails(context); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/repository/OauthRepository.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.repository; 2 | 3 | import com.wanxin.uaa.domain.OauthClientDetails; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author yuelimin 9 | * @version 1.0.0 10 | * @since 1.8 11 | */ 12 | public interface OauthRepository { 13 | 14 | OauthClientDetails findOauthClientDetails(String clientId); 15 | 16 | List findAllOauthClientDetails(); 17 | 18 | void updateOauthClientDetailsArchive(String clientId, boolean archive); 19 | 20 | void saveOauthClientDetails(OauthClientDetails clientDetails); 21 | } 22 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/repository/PasswordHandler.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.repository; 2 | 3 | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; 4 | 5 | /** 6 | * @author yuelimin 7 | * @version 1.0.0 8 | * @since 1.8 9 | */ 10 | public abstract class PasswordHandler { 11 | private PasswordHandler() { 12 | } 13 | 14 | public static String encode(String password) { 15 | BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(); 16 | return encoder.encode(password); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/java/com/wanxin/uaa/service/OauthService.java: -------------------------------------------------------------------------------- 1 | package com.wanxin.uaa.service; 2 | 3 | import com.wanxin.uaa.domain.OauthClientDetails; 4 | import com.wanxin.uaa.domain.OauthClientDetailsDto; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author yuelimin 10 | * @version 1.0.0 11 | * @since 1.8 12 | */ 13 | public interface OauthService { 14 | 15 | OauthClientDetails loadOauthClientDetails(String clientId); 16 | 17 | List loadAllOauthClientDetailsDtos(); 18 | 19 | void archiveOauthClientDetails(String clientId); 20 | 21 | OauthClientDetailsDto loadOauthClientDetailsDto(String clientId); 22 | 23 | void registerClientDetails(OauthClientDetailsDto formDto); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/apollo-env.properties: -------------------------------------------------------------------------------- 1 | dev.meta=http://192.168.158.162:8080 2 | fat.meta=http://192.168.158.162:8080 3 | uat.meta=http://192.168.158.162:8080 4 | pro.meta=http://192.168.158.162:8080 5 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | # -Denv=dev -Dapollo.cluster=DEFAULT -Dserver.port=53020 2 | app: 3 | id: uaa-service 4 | apollo: 5 | meta: http://192.168.158.162:8080 6 | bootstrap: 7 | enabled: true 8 | eagerLoad: 9 | enabled: true 10 | namespaces: application,micro_service.spring-boot-druid,micro_service.spring-boot-http,micro_service.spring-eureka,micro_service.spring-hystrix,micro_service.spring-feign,micro_service.spring-ribbon,micro_service.spring-boot-redis,micro_service.spring-freemarker 11 | 12 | logging: 13 | config: classpath:log4j2-dev.xml 14 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 53020 3 | 4 | spring: 5 | application: 6 | name: uaa-service 7 | main: 8 | allow-bean-definition-overriding: true 9 | banner-mode: 'off' 10 | profiles: 11 | active: dev 12 | -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/static/img/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/wanxinp2p-uaa-service/src/main/resources/static/img/error.png -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/static/img/password.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/wanxinp2p-uaa-service/src/main/resources/static/img/password.png -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/static/img/username.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mikuhuyo/wanxin-p2p/72a63d0cf1128b4ca6e2a5a3cbfbb17768135fdf/wanxinp2p-uaa-service/src/main/resources/static/img/username.png -------------------------------------------------------------------------------- /wanxinp2p-uaa-service/src/main/resources/templates/oauth_error.html: -------------------------------------------------------------------------------- 1 | <#import "/spring.ftl" as spring/> 2 | 3 | 4 | 5 | 授权失败 6 | 11 | 12 | 13 | 14 | 15 |
16 | 授权失败 17 |

sorry

18 |

不小心出错啦!

19 |
20 | 21 | 22 | 23 | --------------------------------------------------------------------------------