first commit

This commit is contained in:
Ray
2026-02-19 03:37:37 +08:00
commit ccfd8c79a4
2813 changed files with 453657 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

View File

@@ -0,0 +1,176 @@
<%@ page language="java" pageEncoding="utf-8"%>
<%@ include file="include/pagetop.jsp"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="include/head.jsp"%>
</head>
<body>
<%@ include file="include/loading.jsp"%>
<%@ include file="include/top.jsp"%>
<%@ include file="include/menu_left.jsp"%>
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START CONTENT -->
<div class="content">
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START CONTAINER -->
<div class="container-default">
<h3>区块链地址管理 </h3>
<%@ include file="include/alert.jsp"%>
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START queryForm -->
<form action="<%=basePath%>normal/adminChannelBlockchainAction!list.action"
method="post" id="queryForm">
<s:hidden name="pageNo" id="pageNo"></s:hidden>
<s:hidden name="name_para" id="name_para"></s:hidden>
</form>
<!-- END queryForm -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<div class="row">
<div class="col-md-12 col-lg-12">
<div class="panel panel-default">
<div class="panel-title">
新增区块链地址
<ul class="panel-tools">
<li><a class="icon minimise-tool"><i
class="fa fa-minus"></i></a></li>
<li><a class="icon expand-tool"><i class="fa fa-expand"></i></a></li>
</ul>
</div>
<div class="panel-body">
<form class="form-horizontal"
action="<%=basePath%>normal/adminChannelBlockchainAction!add.action"
method="post" name="mainForm" id="mainForm">
<s:hidden name="id" id="id"></s:hidden>
<s:hidden name="img" id="img"></s:hidden>
<h5>基础信息</h5>
<div class="form-group">
<label class="col-sm-2 control-label form-label">币种</label>
<div class="col-sm-3">
<s:textfield id="coin" name="coin" cssClass="form-control " />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label form-label">链名称</label>
<div class="col-sm-3">
<s:textfield id="blockchain_name" name="blockchain_name" cssClass="form-control " />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label form-label">地址图片</label>
<div class="col-sm-3">
<input type="file" id="fileName" name="fileName" onchange="upload();" style="position:absolute;opacity:0;">
<label for="fileName">  
      
     <img width="90px" height="90px" id="show_img"
src="<%=base%>admin/www/img/add.png" alt="点击上传图片" />   
  
   </label>   
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label form-label">地址</label>
<div class="col-sm-3">
<s:textfield id="address" name="address" cssClass="form-control " />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<a href="javascript:goUrl(<s:property value="pageNo" />)"
class="btn">取消</a> <a href="javascript:submit()"
class="btn btn-default">保存</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- END CONTAINER -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<%@ include file="include/footer.jsp"%>
</div>
<!-- End Content -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<%@ include file="include/js.jsp"%>
<script type="text/javascript">
function submit() {
swal({
title : "是否保存?",
text : "",
type : "warning",
showCancelButton : true,
confirmButtonColor : "#DD6B55",
confirmButtonText : "确认",
closeOnConfirm : false
}, function() {
document.getElementById("mainForm").submit();
});
}
function upload(){
var fileReader = new FileReader();
var formData = new FormData();
var file = document.getElementById('fileName').files[0];
formData.append("file", file);
$.ajax({
type: "POST",
url: "<%=basePath%>normal/uploadimg!execute.action?random="
+ Math.random(),
data: formData,
dataType: "json",
contentType: false,
processData: false,
success : function(data) {
console.log(data);
$("#img").val(data.data)
var show_img = document.getElementById('show_img');
show_img.src="<%=base%>wap/public/showimg!showImg.action?imagePath="+data.data;
},
error : function(XMLHttpRequest, textStatus,
errorThrown) {
console.log("请求错误");
}
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,169 @@
<%@ page language="java" pageEncoding="utf-8"%>
<%@ include file="include/pagetop.jsp"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="include/head.jsp"%>
</head>
<body>
<%@ include file="include/loading.jsp"%>
<%@ include file="include/top.jsp"%>
<%@ include file="include/menu_left.jsp"%>
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START CONTENT -->
<div class="content">
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START CONTAINER -->
<div class="container-default">
<h3>区块链地址管理</h3>
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START queryForm -->
<%@ include file="include/alert.jsp"%>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-title">查询条件</div>
<div class="panel-body">
<form class="form-horizontal" action="<%=basePath%>normal/adminChannelBlockchainAction!list.action" method="post"
id="queryForm">
<input type="hidden" name="pageNo" id="pageNo"
value="${param.pageNo}">
<div class="col-md-12 col-lg-4">
<fieldset>
<div class="control-group">
<div class="controls">
<s:textfield id="coin_para" name="coin_para" cssClass="form-control " placeholder="币种名称"/>
</div>
</div>
</fieldset>
</div>
<div class="col-md-12 col-lg-4">
<fieldset>
<div class="control-group">
<div class="controls">
<s:textfield id="name_para" name="name_para" cssClass="form-control " placeholder="链名称"/>
</div>
</div>
</fieldset>
</div>
<div class="col-md-12 col-lg-2">
<button type="submit" class="btn btn-light btn-block">查询</button>
</div>
</form>
</div>
</div>
</div>
</div>
<!-- END queryForm -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<div class="row">
<div class="col-md-12">
<!-- Start Panel -->
<div class="panel panel-default">
<div class="panel-title">查询结果</div>
<a href="<%=basePath%>normal/adminChannelBlockchainAction!toAdd.action" class="btn btn-light"
style="margin-bottom: 10px"><i class="fa fa-pencil"></i>新增</a>
<div class="panel-body">
<table class="table table-bordered table-striped">
<thead>
<tr>
<td>币种</td>
<td>链名称名称</td>
<td>图片</td>
<td>地址</td>
<td width="130px"></td>
</tr>
</thead>
<tbody>
<s:iterator value="page.elements" status="stat">
<tr>
<td><s:property value="coin" /></td>
<td><s:property value="blockchain_name" /></td>
<td>
<a href="<%=base%>wap/public/showimg!showImg.action?imagePath=<s:property value="img" />" target="_blank">查看照片</a>
</td>
<td><s:property value="address" /></td>
<td>
<div class="btn-group">
<button type="button" class="btn btn-light">操作</button>
<button type="button" class="btn btn-light dropdown-toggle"
data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span> <span class="sr-only">Toggle
Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li><a href="<%=basePath%>normal/adminChannelBlockchainAction!toUpdate.action?id=<s:property value="id" />">修改</a></li>
<li><a href="<%=basePath%>normal/adminChannelBlockchainAction!toDelete.action?id=<s:property value="id" />">删除</a></li>
</ul>
</div>
</td>
</tr>
</s:iterator>
</tbody>
</table>
<%@ include file="include/page_simple.jsp"%>
<nav>
</div>
</div>
<!-- End Panel -->
</div>
</div>
</div>
<!-- END CONTAINER -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<%@ include file="include/footer.jsp"%>
</div>
<!-- End Content -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<%@ include file="include/js.jsp"%>
<script src="<%=basePath%>js/bootstrap/bootstrap-treeview.js"></script>
<script>
$(function () {
var data = <s:property value="result" escape='false' />;
console.log(data);
$("#treeview4").treeview({
color: "#428bca",
enableLinks:true,
nodeIcon: "glyphicon glyphicon-user",
data: data,
levels: 4,
});
});
</script>
<script type="text/javascript">
</script>
</body>
</html>

View File

@@ -0,0 +1,182 @@
<%@ page language="java" pageEncoding="utf-8"%>
<%@ include file="include/pagetop.jsp"%>
<!DOCTYPE html>
<html>
<head>
<%@ include file="include/head.jsp"%>
</head>
<body>
<%@ include file="include/loading.jsp"%>
<%@ include file="include/top.jsp"%>
<%@ include file="include/menu_left.jsp"%>
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START CONTENT -->
<div class="content">
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START CONTAINER -->
<div class="container-default">
<h3>区块链地址管理</h3>
<%@ include file="include/alert.jsp"%>
<!-- //////////////////////////////////////////////////////////////////////////// -->
<!-- START queryForm -->
<form action="<%=basePath%>normal/adminChannelBlockchainAction!list.action"
method="post" id="queryForm">
<s:hidden name="pageNo" id="pageNo"></s:hidden>
<s:hidden name="name_para" id="name_para"></s:hidden>
</form>
<!-- END queryForm -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<div class="row">
<div class="col-md-12 col-lg-12">
<div class="panel panel-default">
<div class="panel-title">
修改区块链地址
<ul class="panel-tools">
<li><a class="icon minimise-tool"><i
class="fa fa-minus"></i></a></li>
<li><a class="icon expand-tool"><i class="fa fa-expand"></i></a></li>
</ul>
</div>
<div class="panel-body">
<form class="form-horizontal"
action="<%=basePath%>normal/adminChannelBlockchainAction!update.action"
method="post" name="mainForm" id="mainForm">
<s:hidden name="id" id="id"></s:hidden>
<s:hidden name="img" id="img"></s:hidden>
<h5>基础信息</h5>
<div class="form-group">
<label class="col-sm-2 control-label form-label">币种</label>
<div class="col-sm-3">
<s:textfield id="coin" name="coin" cssClass="form-control " />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label form-label">链名称</label>
<div class="col-sm-3">
<s:textfield id="blockchain_name" name="blockchain_name" cssClass="form-control " />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label form-label">地址图片</label>
<div class="col-sm-3">
<input type="file" id="fileName" name="fileName" onchange="upload();" style="position:absolute;opacity:0;">
<label for="fileName">  
      
     <img width="90px" height="90px" id="show_img"
src="<%=base%>admin/www/img/add.png" alt="点击上传图片" />   
  
   </label>   
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label form-label">地址</label>
<div class="col-sm-3">
<s:textfield id="address" name="address" cssClass="form-control " />
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<a href="javascript:goUrl(<s:property value="pageNo" />)"
class="btn">取消</a> <a href="javascript:submit()"
class="btn btn-default">保存</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- END CONTAINER -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<%@ include file="include/footer.jsp"%>
</div>
<!-- End Content -->
<!-- //////////////////////////////////////////////////////////////////////////// -->
<%@ include file="include/js.jsp"%>
<script type="text/javascript">
function submit() {
swal({
title : "是否保存?",
text : "",
type : "warning",
showCancelButton : true,
confirmButtonColor : "#DD6B55",
confirmButtonText : "确认",
closeOnConfirm : false
}, function() {
document.getElementById("mainForm").submit();
});
}
//初始化执行一次
setTimeout(function() {
start();
}, 100);
function start(){
var img = $("#img").val();
var show_img = document.getElementById('show_img');
show_img.src="<%=base%>wap/public/showimg!showImg.action?imagePath="+img;
}
function upload(){
var fileReader = new FileReader();
var formData = new FormData();
var file = document.getElementById('fileName').files[0];
formData.append("file", file);
$.ajax({
type: "POST",
url: "<%=basePath%>normal/uploadimg!execute.action?random="
+ Math.random(),
data: formData,
dataType: "json",
contentType: false,
processData: false,
success : function(data) {
console.log(data);
$("#img").val(data.data)
var show_img = document.getElementById('show_img');
show_img.src="<%=base%>wap/public/showimg!showImg.action?imagePath="+data.data;
},
error : function(XMLHttpRequest, textStatus,
errorThrown) {
console.log("请求错误");
}
});
}
</script>
</body>
</html>

View File

@@ -0,0 +1,3 @@
Manifest-Version: 1.0
Class-Path:

View File

@@ -0,0 +1,8 @@
admin
<!-- recharge -->
<value>adminRechargeOrderService</value>
api
<!-- recharge -->

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<bean id="rechargeChannelFactory"
class="project.recharge.RechargeChannelFactory">
<property name="sysparaService" ref="sysparaService" />
</bean>
</beans>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<bean id="adminRechargeOrderService" class="project.recharge.internal.AdminRechargeOrderServiceImpl">
<property name="pagedQueryDao" ref="pagedDao" />
<property name="userRecomService" ref="userRecomService" />
</bean>
</beans>

View File

@@ -0,0 +1,5 @@
admin
<action name="adminRechargeOrderAction"
class="project.recharge.web.AdminRechargeOrderAction">
<result name="list">/recharge_list.jsp</result>
</action>

View File

@@ -0,0 +1,20 @@
DROP TABLE IF EXISTS `T_RECHARGE_ORDER`;
CREATE TABLE `T_RECHARGE_ORDER` (
`UUID` varchar(32) NOT NULL,
`ORDER_NO` char(32) ,
`CHANNEL_ORDER_NO` varchar(64) ,
`PARTY_ID` varchar(32) ,
`CHANNEL` varchar(32) ,
`AMOUNT` double ,
`CHANNEL_AMOUNT` double ,
`SUCCEEDED` int(11) ,
`CREATED` datetime ,
`EXTRA` varchar(4096) ,
`DESCRIPTION` varchar(256) ,
`FAILURE_MSG` varchar(4096) ,
`CURRENCY` varchar(32) ,
PRIMARY KEY (`UUID`),
KEY `INX_RECHARGE_ORDER_PARTY_ID` (`PARTY_ID`,`CREATED`),
KEY `INX_RECHARGE_ORDER_SUCCEEDED` (`SUCCEEDED`,`CREATED`),
KEY `INX_RECHARGE_ORDER_ORDER_NO` (`ORDER_NO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="${dubbo.application.name}" />
<!-- 使用zkp注册中心暴露服务地址 -->
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry protocol="${dubbo.registry.protocol}"
address="${dubbo.registry.address}" />
<dubbo:protocol host="127.0.0.1" />
<dubbo:reference id="channelBlockchainService"
interface="project.blockchain.ChannelBlockchainService" check="false" />
<dubbo:reference id="rechargeBlockchainService"
interface="project.blockchain.RechargeBlockchainService" check="false" />
<dubbo:reference id="qRProducerService"
interface="project.blockchain.QRProducerService" check="false" />
<dubbo:reference id="rechargeBonusService"
interface="project.bonus.RechargeBonusService" check="false" />
</beans>

View File

@@ -0,0 +1,15 @@
admin
<!-- recharge -->
<value>adminRechargeBlockchainOrderService</value>
<value>adminChannelBlockchainService</value>
api
<!-- recharge -->
<!-- blockchain -->
<value>rechargeBlockchainService</value>
<value>channelBlockchainService</value>
<value>qRProducerService</value>
<value>rechargeBonusService</value>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<bean id="rechargeBlockchainService"
class="project.blockchain.internal.RechargeBlockchainServiceImpl">
<property name="userDataService" ref="userDataService" />
<property name="walletService" ref="walletService" />
<property name="moneyLogService" ref="moneyLogService" />
<property name="exchangeRateService" ref="exchangeRateService" />
<property name="walletLogService" ref="walletLogService" />
<property name="hibernateTemplate" ref="hibernateTemplate" />
<property name="rechargeBonusService" ref="rechargeBonusService" />
<property name="logService" ref="logService" />
<property name="secUserService" ref="secUserService" />
<property name="partyService" ref="partyService" />
<property name="sysparaService" ref="sysparaService" />
<property name="channelBlockchainService" ref="channelBlockchainService" />
<property name="userRecomService" ref="userRecomService" />
</bean>
<dubbo:service
interface="project.blockchain.RechargeBlockchainService" ref="rechargeBlockchainService" />
<bean id="channelBlockchainService"
class="project.blockchain.internal.ChannelBlockchainServiceImpl">
<property name="hibernateTemplate" ref="hibernateTemplate" />
<property name="logService" ref="logService" />
<property name="secUserService" ref="secUserService" />
<property name="passwordEncoder" ref="passwordEncoder" />
</bean>
<dubbo:service
interface="project.blockchain.ChannelBlockchainService"
ref="channelBlockchainService" />
<bean id="qRProducerService"
class="project.blockchain.internal.QRProducerServiceImpl">
</bean>
<dubbo:service
interface="project.blockchain.QRProducerService"
ref="qRProducerService" />
<bean id="rechargeBonusService"
class="project.bonus.internal.RechargeBonusServiceImpl">
<property name="userRecomService" ref="userRecomService" />
<property name="hibernateTemplate" ref="hibernateTemplate" />
<property name="sysparaService" ref="sysparaService" />
<property name="walletLogService" ref="walletLogService" />
<property name="walletService" ref="walletService" />
<property name="moneyLogService" ref="moneyLogService" />
<property name="rechargeBlockchainService" ref="rechargeBlockchainService" />
<property name="userDataService" ref="userDataService" />
<property name="partyService" ref="partyService" />
</bean>
<dubbo:service
interface="project.bonus.RechargeBonusService"
ref="rechargeBonusService" />
</beans>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd ">
<bean id="adminRechargeBlockchainOrderService" class="project.rechargeblockchain.internal.AdminRechargeBlockchainOrderServiceImpl">
<property name="pagedQueryDao" ref="pagedDao" />
<property name="userRecomService" ref="userRecomService" />
<property name="rechargeBlockchainService" ref="rechargeBlockchainService" />
<property name="logService" ref="logService" />
<property name="passwordEncoder" ref="passwordEncoder" />
<property name="hibernateTemplate" ref="hibernateTemplate" />
</bean>
<bean id="adminChannelBlockchainService"
class="project.channelblockchain.internal.AdminChannelBlockchainServiceImpl">
<property name="hibernateTemplate" ref="hibernateTemplate" />
<property name="pagedQueryDao" ref="pagedDao" />
</bean>
</beans>

View File

@@ -0,0 +1,22 @@
admin
<action name="adminChannelBlockchainAction"
class="project.blockchain.web.AdminChannelBlockchainAction">
<result name="list">/channel_blockchain_list.jsp</result>
<result name="add">/channel_blockchain_add.jsp</result>
<result name="update">/channel_blockchain_update.jsp</result>
</action>
<action name="adminRechargeBlockchainOrderAction"
class="project.blockchain.web.AdminRechargeBlockchainOrderAction">
<result name="list">/recharge_blockchain_list.jsp</result>
</action>
api
<action name="rechargeblockchain"
class="project.blockchain.web.RechargeBlockchainAction">
</action>
<action name="channelBlockchain"
class="project.blockchain.web.ChannelBlockchainAction">
</action>

View File

@@ -0,0 +1,37 @@
DROP TABLE IF EXISTS `T_RECHARGE_BLOCKCHAIN_ORDER`;
CREATE TABLE `T_RECHARGE_BLOCKCHAIN_ORDER` (
`UUID` varchar(32) NOT NULL,
`ORDER_NO` char(32) ,
`AMOUNT` double ,
`PARTY_ID` varchar(32) ,
`SUCCEEDED` int(11) ,
`CREATED` datetime ,
`CURRENCY` varchar(32) ,
`DESCRIPTION` varchar(256) ,
`BLOCKCHAIN_NAME` varchar(32) ,
`IMG` varchar(64) ,
`CHANNEL_AMOUNT` double ,
`ADDRESS` varchar(256) ,
PRIMARY KEY (`UUID`),
KEY `INX_RECHARGE_BLOCKCHAIN_ORDER_PARTY_ID` (`PARTY_ID`,`CREATED`),
KEY `INX_RECHARGE_BLOCKCHAIN_ORDER_SUCCEEDED` (`SUCCEEDED`,`CREATED`),
KEY `INX_RECHARGE_BLOCKCHAIN_ORDER_ORDER_NO` (`ORDER_NO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `T_CHANNEL_BLOCKCHAIN`
-- ----------------------------
DROP TABLE IF EXISTS `T_CHANNEL_BLOCKCHAIN`;
CREATE TABLE `T_CHANNEL_BLOCKCHAIN` (
`UUID` varchar(32) NOT NULL COMMENT '主键',
`NAME` varchar(32) DEFAULT NULL,
`IMG` varchar(64) DEFAULT NULL,
`ADDRESS` varchar(64) DEFAULT NULL,
PRIMARY KEY (`UUID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View File

@@ -0,0 +1,20 @@
ALTER TABLE `T_CHANNEL_BLOCKCHAIN`
CHANGE COLUMN `NAME` `BLOCKCHAIN_NAME` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `UUID`,
ADD COLUMN `COIN` varchar(32) NULL AFTER `ADDRESS`;
ALTER TABLE `T_RECHARGE_BLOCKCHAIN_ORDER`
CHANGE COLUMN `CURRENCY` `COIN` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL AFTER `CREATED`;
ALTER TABLE T_RECHARGE_BLOCKCHAIN_ORDER DROP AMOUNT;
ALTER TABLE T_RECHARGE_BLOCKCHAIN_ORDER DROP USDT_AMOUNT;

View File

@@ -0,0 +1,18 @@
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES
('4028abaf735d1dsfsfd3242342342','ERC20','','','USDT');
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES
('4028abaf735d43534242ffds232fs','TRC20','','','USDT');
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES
('4028abaf735d34532423fdsfdf234','OMNI','','','USDT');
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES
('4028abaf735dgds2323dfgfgdfgdf','BTC','','','BTC');
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES
('4028abaf73gdfgs34asdsd2323234','','','','ETH');
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES ('4028ab3d75971b8c01759720744f0001', 'ERC20', '', '', 'HT');
INSERT INTO T_CHANNEL_BLOCKCHAIN VALUES ('4028ab3d759735ba01759739b8bb0003', 'TRC20', '', '', 'HT');

View File

@@ -0,0 +1,17 @@
package project.blockchain;
import kernel.web.Page;
/**
* 后台区块链地址查询
*
*/
public interface AdminChannelBlockchainService {
/**
* 代理分页查询 name_para链名称coin_para币种名称
*/
public Page pagedQuery(int pageNo, int pageSize, String name_para, String coin_para);
Page pagedPersonQuery(int pageNo, int pageSize, String userName, String roleName, String chainName, String coinSymbol, String address);
}

View File

@@ -0,0 +1,51 @@
package project.blockchain;
import java.util.Date;
import java.util.Map;
import kernel.web.Page;
/**
* 后台区块链充值订单查询与到账接口
*
*
*/
public interface AdminRechargeBlockchainOrderService {
public Page pagedQuery(int pageNo, int pageSize, String name_para, Integer state_para, String loginPartyId,String orderNo,String rolename_para,
String startTime,String endTime,String reviewStartTime, String reviewEndTime);
/**
* 管理员手工到账
*/
public Map saveSucceeded(String order_no, String safeword, String operator_username, String transfer_usdt,
String success_amount, double rechargeCommission,String remarks);
/**
* 驳回充值
*
* @param id
* @param failure_msg 驳回原因
*/
public void saveReject(String id, String failure_msg,String userName,String partyId);
/**
* 修改备注信息
*
* @param id
* @param failure_msg 备注信息
*/
public void saveRejectRemark(String id, String failure_msg,String userName,String partyId);
/**
* 某个时间后未处理订单数量,没有时间则全部
* @param time
* @return
*/
public Long getUntreatedCount(Date time, String loginPartyId) ;
/**
* 修改图片信息
*/
public void saveRechargeImg(String id, String img,String safeword,String userName,String partyId);
}

View File

@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.blockchain.ChannelBlockchain" table="T_CHANNEL_BLOCKCHAIN">
<id name="id" type="java.lang.String">
<column name="UUID" />
<generator class="uuid.hex" />
</id>
<property name="coin" type="java.lang.String">
<column name="COIN" />
</property>
<property name="blockchain_name" type="java.lang.String">
<column name="BLOCKCHAIN_NAME" />
</property>
<property name="img" type="java.lang.String">
<column name="IMG" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
<property generated="never" name="auto" type="yes_no">
<column name="AUTO" />
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,119 @@
package project.blockchain;
import kernel.bo.EntityObject;
/**
* 区块链充值地址
*
*/
public class ChannelBlockchain extends EntityObject {
private static final long serialVersionUID = 8611350151193561992L;
/**
* 币种名称 BTC ETH USDT
*/
private String coin;
/**
* 链名称
*/
private String blockchain_name;
/**
* 区块链地址图片
*/
private String img;
/**
* 区块链地址图片,不带链接
*/
private String img_str;
/**
* 区块链地址
*/
private String address;
/**
* 汇率
*/
private double fee = 1;
private double recharge_limit_min = 1;
private double recharge_limit_max = 1;
/**
* 手动/自动到账
*/
private boolean auto = false;
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCoin() {
return coin;
}
public void setCoin(String coin) {
this.coin = coin;
}
public String getBlockchain_name() {
return blockchain_name;
}
public void setBlockchain_name(String blockchain_name) {
this.blockchain_name = blockchain_name;
}
public String getImg_str() {
return img_str;
}
public void setImg_str(String img_str) {
this.img_str = img_str;
}
public boolean getAuto() {
return this.auto;
}
public void setAuto(boolean auto) {
this.auto = auto;
}
public double getFee() {
return fee;
}
public void setFee(double fee) {
this.fee = fee;
}
public double getRecharge_limit_min() {
return recharge_limit_min;
}
public void setRecharge_limit_min(double recharge_limit_min) {
this.recharge_limit_min = recharge_limit_min;
}
public double getRecharge_limit_max() {
return recharge_limit_max;
}
public void setRecharge_limit_max(double recharge_limit_max) {
this.recharge_limit_max = recharge_limit_max;
}
}

View File

@@ -0,0 +1,63 @@
package project.blockchain;
import java.util.List;
/**
* 链入地址
*/
public interface ChannelBlockchainService {
/**
* 地址添加
*/
public void save(ChannelBlockchain channelBlockchain, String userName, String safeword, String login_ip,
String code, String superGoogleAuthCode);
/**
* 地址更新
*/
public void update(ChannelBlockchain old, ChannelBlockchain channelBlockchain, String userName, String partyId,
String safeword, String login_ip, String code, String superGoogleAuthCode);
public ChannelBlockchain findById(String id);
public ChannelBlockchain findByNameAndCoinAndAdd(String blockchain_name, String coin,String address);
/**
* 地址删除
*
* @param id
* @param safeword 资金密码
* @param userName 登录人
* @param loginIp ip
* @param code 验证码
*/
public void delete(String id, String safeword, String userName, String loginIp, String code,
String superGoogleAuthCode);
public List<ChannelBlockchain> findAll();
/**
* @param coin
* @return
*/
public List<ChannelBlockchain> findByCoin(String coin);
/**
* @param coin
* @param blockchain_name
* @return
*/
public List<ChannelBlockchain> findByCoinAndName(String coin, String blockchain_name);
/**
* 过滤充值地址链,随机获取
*
* @param list
* @return
*/
public List<ChannelBlockchain> filterBlockchain(List<ChannelBlockchain> list);
PartyBlockchain findPersonBlockchain(String username,String coinSymbol);
}

View File

@@ -0,0 +1,41 @@
package project.blockchain;
import java.io.Serializable;
public enum ChannelStateEnum implements Serializable {
STATE_SUCCESS("0", "成功"), STATE_FAIL("1", "失败"), STATE_UNKNOWN("3", "状态未知"), STATE_OTHER("4", "其它");
private String code;
private String msg;
ChannelStateEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
public static String getMsgByCode(String code) {
for (ChannelStateEnum rspMsgEnum : ChannelStateEnum.values()) {
if (rspMsgEnum.getCode().equals(code)) {
return rspMsgEnum.getMsg();
}
}
return "未知错误";
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@@ -0,0 +1,84 @@
package project.blockchain;
import java.io.UnsupportedEncodingException;
import java.security.SignatureException;
import org.apache.commons.codec.digest.DigestUtils;
/**
*/
public class MD5 {
/**
* 签名字符串
*
* @param text 需要签名的字符串
* @param key 密钥
* @param input_charset 编码格式
* @return 签名结果
*/
public static String sign(String text, String key, String input_charset) {
text = text + key;
return sign(text, input_charset);
}
/**
*
* sign
*
* @param text
* @param input_charset
* @return
* @创建日期2017年5月6日下午7:04:05
*/
public static String sign(String text, String input_charset) {
return DigestUtils.md5Hex(getContentBytes(text, input_charset));
}
/**
*
* @param text
* @return
*/
public static String sign(String text) {
return sign(text, "utf-8");
}
/**
* 签名字符串
*
* @param text 需要签名的字符串
* @param sign 签名结果
* @param key 密钥
* @param input_charset 编码格式
* @return 签名结果
*/
public static boolean verify(String text, String sign, String key, String input_charset) {
text = text + key;
String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));
if (mysign.equals(sign)) {
return true;
} else {
return false;
}
}
/**
* @param content
* @param charset
* @return
* @throws SignatureException
* @throws UnsupportedEncodingException
*/
private static byte[] getContentBytes(String content, String charset) {
if (charset == null || "".equals(charset)) {
return content.getBytes();
}
try {
return content.getBytes(charset);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
}
}
}

View File

@@ -0,0 +1,33 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.blockchain.PartyBlockchain" table="T_PARTY_BLOCKCHAIN">
<id name="id" type="java.lang.String">
<column name="UUID" />
<generator class="uuid.hex" />
</id>
<property name="userName" type="java.lang.String">
<column name="USER_NAME" />
</property>
<property name="chainName" type="java.lang.String">
<column name="CHAIN_NAME" />
</property>
<property name="coinSymbol" type="java.lang.String">
<column name="COIN_SYMBOL" />
</property>
<property name="qrImage" type="java.lang.String">
<column name="QR_IMAGE" />
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS" />
</property>
<property name="auto" type="java.lang.String">
<column name="AUTO" />
</property>
<property name="createTime" type="java.util.Date">
<column name="CREATE_TIME" />
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,97 @@
package project.blockchain;
import kernel.bo.EntityObject;
import java.util.Date;
/**
* 个人区块链充值地址
*
*/
public class PartyBlockchain extends EntityObject {
private static final long serialVersionUID = 8087327604778650102L;
/**
* 用户名
*/
private String userName;
/**
* 链名称
*/
private String chainName;
/**
*
*/
private String coinSymbol;
/**
* 区块链地址图片,不带链接
*/
private String qrImage;
/**
* 区块链地址图片,不带链接
*/
private String address;
/**
* 自动/手动到账
*/
private String auto;
private Date createTime;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getChainName() {
return chainName;
}
public void setChainName(String chainName) {
this.chainName = chainName;
}
public String getCoinSymbol() {
return coinSymbol;
}
public void setCoinSymbol(String coinSymbol) {
this.coinSymbol = coinSymbol;
}
public String getQrImage() {
return qrImage;
}
public void setQrImage(String qrImage) {
this.qrImage = qrImage;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAuto() {
return auto;
}
public void setAuto(String auto) {
this.auto = auto;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@@ -0,0 +1,18 @@
package project.blockchain;
/**
*
* 二维码图片生产者
*
*/
public interface QRProducerService {
/**
* 生成二维码图片
*
* @param content
* 二维码内容
* @return 图片url地址
*/
public String generate(String content);
}

View File

@@ -0,0 +1,22 @@
package project.blockchain;
import java.util.HashSet;
import java.util.Set;
public class RechargeBlochainLock {
private static final Set<String> filterRechargeBlochainLock = new HashSet<String>();
public static boolean add(String partyId) {
if (!filterRechargeBlochainLock.add(partyId)) {
return false;
} else {
return true;
}
}
public static void remove(String partyId) {
filterRechargeBlochainLock.remove(partyId);
}
}

View File

@@ -0,0 +1,57 @@
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="project.blockchain.RechargeBlockchain" table="T_RECHARGE_BLOCKCHAIN_ORDER">
<id name="id" type="java.lang.String">
<column name="UUID"/>
<generator class="uuid.hex"/>
</id>
<property name="order_no" type="java.lang.String">
<column name="ORDER_NO"/>
</property>
<property name="partyId" type="java.lang.String">
<column name="PARTY_ID"/>
</property>
<property name="succeeded" type="java.lang.Integer">
<column name="SUCCEEDED"/>
</property>
<property name="created" type="timestamp">
<column name="CREATED"/>
</property>
<property name="description" type="java.lang.String">
<column name="DESCRIPTION"/>
</property>
<property name="symbol" type="java.lang.String">
<column name="COIN"/>
</property>
<property name="blockchain_name" type="java.lang.String">
<column name="BLOCKCHAIN_NAME"/>
</property>
<property name="img" type="java.lang.String">
<column name="IMG"/>
</property>
<property name="amount" type="double">
<column name="AMOUNT"/>
</property>
<property name="volume" type="double">
<column name="CHANNEL_AMOUNT"/>
</property>
<property name="address" type="java.lang.String">
<column name="ADDRESS"/>
</property>
<property name="channel_address" type="java.lang.String">
<column name="CHANNEL_ADDRESS"/>
</property>
<property name="reviewTime" type="timestamp">
<column name="REVIEWTIME"/>
</property>
<property name="tx" type="java.lang.String">
<column name="TX"/>
</property>
<property name="rechargeCommission" type="double">
<column name="RECHARGE_COMMISSION"/>
</property>
</class>
</hibernate-mapping>

View File

@@ -0,0 +1,207 @@
package project.blockchain;
import java.io.Serializable;
import java.util.Date;
import kernel.bo.EntityObject;
/**
* 区块链充值订单
*/
public class RechargeBlockchain extends EntityObject {
/**
*
*/
private static final long serialVersionUID = -4483090797419171871L;
/**
* 订单号
*/
private String order_no;
private Serializable partyId;
/**
* 充值数量,原始币种的金额
*/
private Double volume;
/**
* 充值币种
*/
private String symbol;
/**
* 充值状态 0 初始状态,未知或处理中 1 成功 2 失败
*/
private int succeeded = 0;
/**
* 创建时间
*/
private Date created;
/**
* 审核操作时间
*/
private Date reviewTime;
/**
* 备注说明,管理员操作
*/
private String description;
/**
* 区块链充值地址
*/
private String blockchain_name;
/**
* 已充值的上传图片
*/
private String img;
/**
* 客户自己的区块链地址
*/
private String address;
/**
* 通道充值地址
*/
private String channel_address;
/**
* 转账hash
*/
private String tx;
/**
* 实际到账金额,换算成 USDT 单位的金额
*/
private Double amount;
/**
* 业务员提成
*/
private Double rechargeCommission = 0.0;
public String getOrder_no() {
return order_no;
}
public void setOrder_no(String order_no) {
this.order_no = order_no;
}
public Serializable getPartyId() {
return partyId;
}
public void setPartyId(Serializable partyId) {
this.partyId = partyId;
}
public int getSucceeded() {
return succeeded;
}
public void setSucceeded(int succeeded) {
this.succeeded = succeeded;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getBlockchain_name() {
return blockchain_name;
}
public void setBlockchain_name(String blockchain_name) {
this.blockchain_name = blockchain_name;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getVolume() {
return volume;
}
public void setVolume(Double volume) {
this.volume = volume;
}
public String getSymbol() {
return symbol;
}
public void setSymbol(String symbol) {
this.symbol = symbol;
}
public Date getReviewTime() {
return reviewTime;
}
public void setReviewTime(Date reviewTime) {
this.reviewTime = reviewTime;
}
public String getChannel_address() {
return channel_address;
}
public void setChannel_address(String channel_address) {
this.channel_address = channel_address;
}
public String getTx() {
return tx;
}
public void setTx(String tx) {
this.tx = tx;
}
public Double getAmount() {
return amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
public Double getRechargeCommission() {
return rechargeCommission;
}
public void setRechargeCommission(Double rechargeCommission) {
this.rechargeCommission = rechargeCommission;
}
}

View File

@@ -0,0 +1,76 @@
package project.blockchain;
import project.withdraw.Withdraw;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
/**
* 区块链充值订单接口
*
* @author User
*
*/
public interface RechargeBlockchainService {
public void save(RechargeBlockchain recharge, double exchangeRate);
public void save_api(RechargeBlockchain recharge);
public void update(RechargeBlockchain recharge);
public RechargeBlockchain findByOrderNo(String order_no);
/**
* 查找当日内用户的所有充值订单
*
* @param partyId
* @return
*/
public List<RechargeBlockchain> findByPartyIdAndToday(Serializable partyId);
/**
* 查找所有用户几天前的指定一天的的所有充值订单
*
* @param succeeded days 几天前
* @return
*/
public List<RechargeBlockchain> findBySucceededAndDay(int succeeded, Integer days);
/**
*
* @param order_no
*/
public Map saveSucceeded(String order_no, String operator, String transfer_usdt, String success_amount, double rechargeCommission,String remarks);
/**
*
* @param recharge
*/
public boolean saveReject(RechargeBlockchain recharge);
/**
* 是否是商家首次充值成功
* @param order_no
* @return
*/
public boolean updateFirstSuccessRecharge(String order_no);
/**
* 查询充值成功的订单条数
* @param partyId
* @return
*/
public List<RechargeBlockchain> findSuccessByPartyId(Serializable partyId);
List<RechargeBlockchain> selectUnFinishedRecharge(String partyId);
double getComputeRechargeAmount(String partyId);
/**
* 根据充值订单单号,赠送拉人礼金
* @param order_no
*/
void updateFirstSuccessInviteReward(String order_no);
}

View File

@@ -0,0 +1,81 @@
package project.blockchain.event;
import com.alibaba.fastjson.JSON;
import kernel.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import project.blockchain.RechargeBlockchainService;
import project.blockchain.event.message.RechargeSuccessEvent;
import project.blockchain.event.model.RechargeInfo;
import project.party.UserMetricsService;
import project.party.model.UserMetrics;
import project.wallet.WalletLogService;
import java.util.Date;
/**
* 用户充值审核通过后,有一些关联业务会同步受到影响
* 目前可见受影响的业务数据:
* 1. 更新用户累计充值金额指标统计记录:
* 2. ....
*
*/
public class RechargeSuccessEventListener implements ApplicationListener<RechargeSuccessEvent> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private RechargeBlockchainService rechargeBlockchainService;
private WalletLogService walletLogService;
private UserMetricsService userMetricsService;
@Override
public void onApplicationEvent(RechargeSuccessEvent event) {
RechargeInfo changeInfo = event.getRechargeInfo();
logger.info("监听到用户成功充值事件:" + JSON.toJSONString(changeInfo));
try {
// double rechargeAcc = rechargeBlockchainService.computeRechargeAmount(changeInfo.getApplyUserId());
double rechargeAcc = walletLogService.getComputeRechargeAmount(changeInfo.getApplyUserId());
Date now = new Date();
UserMetrics userMetrics = userMetricsService.getByPartyId(changeInfo.getApplyUserId());
if (userMetrics == null) {
userMetrics = new UserMetrics();
userMetrics.setAccountBalance(0.0D);
userMetrics.setMoneyRechargeAcc(0.0D);
userMetrics.setMoneyWithdrawAcc(0.0D);
userMetrics.setPartyId(changeInfo.getApplyUserId());
userMetrics.setStatus(1);
userMetrics.setTotleIncome(0.0D);
userMetrics.setCreateTime(now);
userMetrics.setUpdateTime(now);
userMetrics = userMetricsService.save(userMetrics);
}
userMetrics.setStoreMoneyRechargeAcc(userMetrics.getStoreMoneyRechargeAcc()+changeInfo.getAmount());
userMetrics.setMoneyRechargeAcc(rechargeAcc);
userMetricsService.update(userMetrics);
} catch (Exception e) {
logger.error("用户充值审核通过后,更新用户的相关指标数据报错,变更信息为:{}", JsonUtils.getJsonString(changeInfo), e);
}
}
public void setRechargeBlockchainService(RechargeBlockchainService rechargeBlockchainService) {
this.rechargeBlockchainService = rechargeBlockchainService;
}
public void setWalletLogService(WalletLogService walletLogService) {
this.walletLogService = walletLogService;
}
public void setUserMetricsService(UserMetricsService userMetricsService) {
this.userMetricsService = userMetricsService;
}
}

View File

@@ -0,0 +1,199 @@
package project.blockchain.event;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import kernel.constants.ValueTypeEnum;
import kernel.util.Arith;
import kernel.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import project.Constants;
import project.RedisKeys;
import project.blockchain.RechargeBlockchainService;
import project.blockchain.event.message.RechargeSuccessEvent;
import project.blockchain.event.model.RechargeInfo;
import project.blockchain.internal.FundChangeService;
import project.log.MoneyLog;
import project.mall.seller.MallLevelService;
import project.mall.seller.SellerService;
import project.mall.seller.constant.UpgradeMallLevelCondParamTypeEnum;
import project.mall.seller.dto.MallLevelCondExpr;
import project.mall.seller.dto.MallLevelDTO;
import project.mall.seller.model.MallLevel;
import project.mall.seller.model.Seller;
import project.party.PartyService;
import project.party.UserMetricsService;
import project.party.model.Party;
import project.party.model.UserMetrics;
import project.party.model.UserRecom;
import project.party.recom.UserRecomService;
import project.redis.RedisHandler;
import project.syspara.SysParaCode;
import project.syspara.Syspara;
import project.syspara.SysparaService;
import project.wallet.Wallet;
import project.wallet.WalletLog;
import project.wallet.WalletLogService;
import project.wallet.WalletService;
import java.io.Serializable;
import java.util.*;
/**
* 用户充值审核通过后,有一些关联业务会同步受到影响
* 目前可见受影响的业务数据:
* 1. 检查当前充值用户是否满足升级指标:
* 2. 检查当前充值用户直接上级代理是否满足升级指标
*
*/
public class UpgradeSellerLevelByRechargeEventListener implements ApplicationListener<RechargeSuccessEvent> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private WalletLogService walletLogService;
private SellerService sellerService;
private PartyService partyService;
private UserRecomService userRecomService;
private MallLevelService mallLevelService;
private SysparaService sysparaService;
private FundChangeService fundChangeService;
private RedisHandler redisHandler;
@Override
public void onApplicationEvent(RechargeSuccessEvent event) {
RechargeInfo changeInfo = event.getRechargeInfo();
logger.info("监听到用户成功充值事件,将判断当前用户或相关用户等级是否满足提升指标:" + JSON.toJSONString(changeInfo));
try {
Date now = new Date();
redisHandler.zadd(RedisKeys.RECHARGE_PASS_TIME, now.getTime(), changeInfo.getApplyUserId());
Seller sellerEntity = sellerService.getSeller(changeInfo.getApplyUserId());
if (sellerEntity == null) {
// 不是商家类型用户,不做后续处理
return;
}
Party currentParty = this.partyService.getById(changeInfo.getApplyUserId());
// 上级推荐人
String parentPartyId = "";
UserRecom firstRecom = userRecomService.findByPartyId(currentParty.getId().toString());
if (firstRecom != null) {
Party parentParty = this.partyService.getById(firstRecom.getReco_id().toString());
if (parentParty != null) {
parentPartyId = parentParty.getId().toString();
}
}
// 提取用于店铺升级业务的有效充值用户的充值金额临界值
double limitRechargeAmount = 100.0;
// 提取用于店铺升级业务的计算团队人数充值金额临界值
double limitRechargeAmountOnTeam = 100.0;
Syspara syspara = sysparaService.find(SysParaCode.VALID_RECHARGE_AMOUNT_FOR_SELLER_UPGRADE.getCode());
Syspara sysparaOnTeam = sysparaService.find(SysParaCode.VALID_RECHARGE_AMOUNT_FOR_TEAM_NUM.getCode());
if (syspara != null) {
String validRechargeAmountInfo = syspara.getValue().trim();
if (StrUtil.isNotBlank(validRechargeAmountInfo)) {
limitRechargeAmount = Double.parseDouble(validRechargeAmountInfo);
}
}
if (sysparaOnTeam != null) {
String rechargeAmountOnTeamInfo = sysparaOnTeam.getValue().trim();
if (StrUtil.isNotBlank(rechargeAmountOnTeamInfo)) {
limitRechargeAmountOnTeam = Double.parseDouble(rechargeAmountOnTeamInfo);
}
}
// 对等级集合进行排序,方便升级判断
List<MallLevel> levelEntityList = this.mallLevelService.listLevel();
Map<String, Integer> levelSortMap = new HashMap<>();
levelSortMap.put("C", 1);
levelSortMap.put("B", 2);
levelSortMap.put("A", 3);
levelSortMap.put("S", 4);
levelSortMap.put("SS", 5);
levelSortMap.put("SSS", 6);
CollUtil.sort(levelEntityList, new Comparator<MallLevel>() {
@Override
public int compare(MallLevel o1, MallLevel o2) {
Integer seq1 = levelSortMap.get(o1.getLevel());
Integer seq2 = levelSortMap.get(o2.getLevel());
seq1 = seq1 == null ? 0 : seq1;
seq2 = seq2 == null ? 0 : seq2;
return seq1 - seq2;
}
});
// 处理当前用户的升级
fundChangeService.upgradeMallLevelProcess(changeInfo.getApplyUserId(), limitRechargeAmount, limitRechargeAmountOnTeam,
levelEntityList, levelSortMap,changeInfo.getAmount());
// =================== 顺别识别当前充值用户的直接上级商家是否满足升级条件 =========================
if (StrUtil.isBlank(parentPartyId) || Objects.equals(parentPartyId, "0")) {
logger.info("-------> UpgradeSellerLevelByRechargeEventListener.onApplicationEvent 当前用户:{} 的上级商家不存在,不再处理上级商家的升级判断处理",
changeInfo.getApplyUserId());
return;
}
// 处理当前用户的直接上级用户的升级逻辑
fundChangeService.upgradeMallLevelProcess(parentPartyId, limitRechargeAmount, limitRechargeAmountOnTeam,
levelEntityList, levelSortMap,0.0);
} catch (Exception e) {
logger.error("用户充值审核通过后,计算更新相关用户的店铺等级处理报错,变更信息为:{} ", JsonUtils.getJsonString(changeInfo), e);
}
}
public void setWalletLogService(WalletLogService walletLogService) {
this.walletLogService = walletLogService;
}
public void setSellerService(SellerService sellerService) {
this.sellerService = sellerService;
}
public void setPartyService(PartyService partyService) {
this.partyService = partyService;
}
public void setUserRecomService(UserRecomService userRecomService) {
this.userRecomService = userRecomService;
}
public void setMallLevelService(MallLevelService mallLevelService) {
this.mallLevelService = mallLevelService;
}
public void setSysparaService(SysparaService sysparaService) {
this.sysparaService = sysparaService;
}
public void setFundChangeService(FundChangeService fundChangeService) {
this.fundChangeService = fundChangeService;
}
public void setRedisHandler(RedisHandler redisHandler) {
this.redisHandler = redisHandler;
}
}

View File

@@ -0,0 +1,17 @@
package project.blockchain.event.message;
import org.springframework.context.ApplicationEvent;
import project.blockchain.event.model.RechargeInfo;
public class RechargeSuccessEvent extends ApplicationEvent {
private RechargeInfo info;
public RechargeSuccessEvent(Object source, RechargeInfo info) {
super(source);
this.info = info;
}
public RechargeInfo getRechargeInfo() {
return this.info;
}
}

View File

@@ -0,0 +1,19 @@
package project.blockchain.event.model;
import lombok.Data;
import java.util.Date;
@Data
public class RechargeInfo {
// 该值可能为空,给用户直接打钱时
private String orderNo;
private double amount;
private String applyUserId;
private String walletLogId;
private Date eventTime;
}

View File

@@ -0,0 +1,19 @@
package project.blockchain.event.model;
import lombok.Data;
import java.util.Date;
@Data
public class WithdrawInfo {
// 该值可能为空
private String orderNo;
private double amount;
private String applyUserId;
private String walletLogId;
private Date eventTime;
}

View File

@@ -0,0 +1,61 @@
package project.blockchain.internal;
import java.util.HashMap;
import java.util.Map;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import kernel.util.StringUtils;
import kernel.web.Page;
import kernel.web.PagedQueryDao;
import project.blockchain.AdminChannelBlockchainService;
public class AdminChannelBlockchainServiceImpl extends HibernateDaoSupport implements AdminChannelBlockchainService {
private PagedQueryDao pagedQueryDao;
public Page pagedQuery(int pageNo, int pageSize, String name_para, String coin_para) {
StringBuffer queryString = new StringBuffer(
" SELECT channelblockchain.UUID id,channelblockchain.BLOCKCHAIN_NAME blockchain_name,"
+ "channelblockchain.IMG img ,channelblockchain.COIN coin, "
+ " channelblockchain.ADDRESS address ");
queryString.append(" FROM T_CHANNEL_BLOCKCHAIN channelblockchain WHERE 1 = 1 ");
Map<String, Object> parameters = new HashMap<>();
if (!StringUtils.isNullOrEmpty(name_para)) {
queryString.append(" and channelblockchain.BLOCKCHAIN_NAME like :name ");
parameters.put("name", "%" + name_para + "%");
}
if (!StringUtils.isNullOrEmpty(coin_para)) {
queryString.append(" and channelblockchain.COIN like :coin ");
parameters.put("coin", "%" + coin_para + "%");
}
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
return page;
}
@Override
public Page pagedPersonQuery(int pageNo, int pageSize, String userName, String roleName, String chainName, String coinSymbol, String address) {
StringBuffer queryString = new StringBuffer(
" SELECT USER_NAME,party.ROLENAME,party.USERCODE,CHAIN_NAME,COIN_SYMBOL,ADDRESS,AUTO,chain.CREATE_TIME FROM T_PARTY_BLOCKCHAIN chain " +
"LEFT JOIN PAT_PARTY party ON party.USERNAME = chain.USER_NAME WHERE 1 = 1 ");
Map<String, Object> parameters = new HashMap<>();
if (!StringUtils.isNullOrEmpty(address)) {
queryString.append(" AND chain.ADDRESS =:address ");
parameters.put("address", address);
}
if (!StringUtils.isNullOrEmpty(userName)) {
queryString.append(" AND (chain.USER_NAME LIKE :userName OR party.USERCODE LIKE :userName) ");
parameters.put("userName", "%" + userName + "%");
}
if (!StringUtils.isNullOrEmpty(roleName)) {
queryString.append(" AND party.ROLENAME = :roleName ");
parameters.put("roleName", roleName);
}
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
return page;
}
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
this.pagedQueryDao = pagedQueryDao;
}
}

View File

@@ -0,0 +1,300 @@
package project.blockchain.internal;
import kernel.exception.BusinessException;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
import kernel.web.Page;
import kernel.web.PagedQueryDao;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.security.providers.encoding.PasswordEncoder;
import project.Constants;
import project.blockchain.AdminRechargeBlockchainOrderService;
import project.blockchain.RechargeBlockchain;
import project.blockchain.RechargeBlockchainService;
import project.log.Log;
import project.log.LogService;
import project.party.recom.UserRecomService;
import project.tip.TipService;
import project.wallet.WalletLog;
import project.wallet.WalletLogService;
import security.SecUser;
import security.internal.SecUserService;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class AdminRechargeBlockchainOrderServiceImpl extends HibernateDaoSupport
implements AdminRechargeBlockchainOrderService {
private final Logger debugLogger = LoggerFactory.getLogger(this.getClass());
private PagedQueryDao pagedQueryDao;
private UserRecomService userRecomService;
private PasswordEncoder passwordEncoder;
private RechargeBlockchainService rechargeBlockchainService;
private LogService logService;
private WalletLogService walletLogService;
private SecUserService secUserService;
private TipService tipService;
@Override
public Page pagedQuery(int pageNo, int pageSize, String name_para, Integer state_para, String loginPartyId,
String orderNo, String rolename_para, String startTime, String endTime, String reviewStartTime, String reviewEndTime) {
StringBuffer queryString = new StringBuffer();
queryString.append("SELECT");
queryString.append(" party.USERNAME username ,party.ROLENAME rolename,party.USERCODE usercode, party.REMARKS remarks, ");
queryString.append(" recharge.UUID id,recharge.ORDER_NO order_no,recharge.BLOCKCHAIN_NAME blockchanin_name, "
+ "recharge.IMG img, recharge.TX hash, recharge.CREATED created, recharge.DESCRIPTION description, ");
queryString.append(" recharge.COIN coin,recharge.REVIEWTIME reviewTime, recharge.AMOUNT amount, "
+ "recharge.SUCCEEDED succeeded,recharge.CHANNEL_AMOUNT channel_amount, recharge.RECHARGE_COMMISSION rechargeCommission,"
+ "recharge.ADDRESS address,recharge.CHANNEL_ADDRESS channel_address, party_parent.USERNAME username_parent ");
queryString.append(" FROM ");
queryString.append(
" T_RECHARGE_BLOCKCHAIN_ORDER recharge "
+ "LEFT JOIN PAT_PARTY party ON recharge.PARTY_ID = party.UUID "
+ " LEFT JOIN PAT_USER_RECOM user ON user.PARTY_ID = party.UUID "
+ " LEFT JOIN PAT_PARTY party_parent ON user.RECO_ID = party_parent.UUID "
+ " ");
queryString.append(" WHERE 1=1 ");
Map<String, Object> parameters = new HashMap<String, Object>();
if (!StringUtils.isNullOrEmpty(loginPartyId)) {
List children = this.userRecomService.findChildren(loginPartyId);
if (children.size() == 0) {
// return Page.EMPTY_PAGE;
return new Page();
}
queryString.append(" and recharge.PARTY_ID in (:children) ");
parameters.put("children", children);
}
// if (!StringUtils.isNullOrEmpty(name_para)) {
// queryString.append(" and (party.USERNAME like :name_para or party.USERCODE =:usercode) ");
// parameters.put("name_para", "%" + name_para + "%");
// parameters.put("usercode", name_para);
//
// }
if (!StringUtils.isNullOrEmpty(name_para)) {
queryString.append("AND (party.USERNAME like:username OR party.USERCODE like:username ) ");
parameters.put("username", "%" + name_para + "%");
}
if (!StringUtils.isNullOrEmpty(rolename_para)) {
queryString.append(" and party.ROLENAME =:rolename");
parameters.put("rolename", rolename_para);
}
if (!StringUtils.isNullOrEmpty(orderNo)) {
queryString.append(" and recharge.ORDER_NO = :orderNo ");
parameters.put("orderNo", orderNo);
}
if (state_para != null) {
queryString.append(" and recharge.SUCCEEDED = :succeeded ");
parameters.put("succeeded", state_para);
}
if (!StringUtils.isNullOrEmpty(startTime) && !StringUtils.isNullOrEmpty(endTime)) {
queryString.append(" AND DATE(recharge.CREATED) >= DATE(:startTime) ");
parameters.put("startTime", DateUtils.toDate(startTime));
queryString.append(" AND DATE(recharge.CREATED) <= DATE(:endTime) ");
parameters.put("endTime", DateUtils.toDate(endTime));
}
if (!StringUtils.isNullOrEmpty(reviewStartTime) && !StringUtils.isNullOrEmpty(reviewEndTime)) {
queryString.append(" AND DATE(recharge.REVIEWTIME) >= DATE(:reviewStartTime) ");
parameters.put("reviewStartTime", DateUtils.toDate(reviewStartTime));
queryString.append(" AND DATE(recharge.REVIEWTIME) <= DATE(:reviewEndTime) ");
parameters.put("reviewEndTime", DateUtils.toDate(reviewEndTime));
}
queryString.append(" order by recharge.CREATED desc ");
Page page = this.pagedQueryDao.pagedQuerySQL(pageNo, pageSize, queryString.toString(), parameters);
return page;
}
@Override
public Map saveSucceeded(String order_no, String safeword, String operator_username, String transfer_usdt, String success_amount, double rechargeCommission,String remarks) {
SecUser sec = this.secUserService.findUserByLoginName(operator_username);
String sysSafeword = sec.getSafeword();
String safeword_md5 = passwordEncoder.encodePassword(safeword, operator_username);
if (!safeword_md5.equals(sysSafeword)) {
throw new BusinessException("资金密码错误");
}
Map map = rechargeBlockchainService.saveSucceeded(order_no, operator_username, transfer_usdt, success_amount, rechargeCommission,remarks);
try {
rechargeBlockchainService.updateFirstSuccessRecharge(order_no);
} catch (Exception e) {
logger.error("判断首充礼金报错,报错信息为:" , e);
}
// 首次充值满足条件赠送邀请礼金
try {
rechargeBlockchainService.updateFirstSuccessInviteReward(order_no);
} catch (Exception e) {
logger.error("判断邀请奖励报错,报错信息为:" , e);
}
return map;
}
/**
* 某个时间后未处理订单数量,没有时间则全部
*
* @param time
* @return
*/
public Long getUntreatedCount(Date time, String loginPartyId) {
StringBuffer queryString = new StringBuffer();
queryString.append("SELECT COUNT(*) FROM RechargeBlockchain WHERE succeeded=0 ");
List<Object> para = new ArrayList<Object>();
if (!StringUtils.isNullOrEmpty(loginPartyId)) {
String childrensIds = this.userRecomService.findChildrensIds(loginPartyId);
if (StringUtils.isEmptyString(childrensIds)) {
return 0L;
}
queryString.append(" and partyId in (" + childrensIds + ") ");
}
if (null != time) {
queryString.append("AND created > ?");
para.add(time);
}
List find = this.getHibernateTemplate().find(queryString.toString(), para.toArray());
return CollectionUtils.isEmpty(find) ? 0L : find.get(0) == null ? 0L : Long.valueOf(find.get(0).toString());
}
public RechargeBlockchain get(String id) {
return this.getHibernateTemplate().get(RechargeBlockchain.class, id);
}
@Override
public void saveReject(String id, String failure_msg, String userName, String partyId) {
RechargeBlockchain recharge = this.get(id);
// 通过后不可驳回
if (recharge.getSucceeded() == 2 || recharge.getSucceeded() == 1) {
return;
}
Date date = new Date();
recharge.setReviewTime(date);
recharge.setSucceeded(2);
recharge.setDescription(failure_msg);
this.getHibernateTemplate().update(recharge);
WalletLog walletLog = walletLogService.find(Constants.MONEYLOG_CATEGORY_RECHARGE, recharge.getOrder_no());
walletLog.setStatus(recharge.getSucceeded());
walletLogService.update(walletLog);
SecUser sec = this.secUserService.findUserByPartyId(recharge.getPartyId());
Log log = new Log();
log.setCategory(Constants.LOG_CATEGORY_OPERATION);
log.setExtra(recharge.getOrder_no());
log.setUsername(sec.getUsername());
log.setOperator(userName);
log.setPartyId(partyId);
log.setLog("管理员驳回一笔充值订单。充值订单号[" + recharge.getOrder_no() + "],驳回理由[" + recharge.getDescription() + "]。");
logService.saveSync(log);
tipService.deleteTip(id);
debugLogger.info("-----> 充值订单:{} 审核拒绝,提交了相关的提示消息删除请求", id);
}
@Override
public void saveRejectRemark(String id, String failure_msg, String userName, String partyId) {
RechargeBlockchain recharge = this.get(id);
String before_failure_msg = recharge.getDescription();
recharge.setDescription(failure_msg);
this.getHibernateTemplate().update(recharge);
SecUser sec = this.secUserService.findUserByPartyId(recharge.getPartyId());
Log log = new Log();
log.setCategory(Constants.LOG_CATEGORY_OPERATION);
log.setExtra(recharge.getOrder_no());
log.setUsername(sec.getUsername());
log.setOperator(userName);
log.setPartyId(partyId);
log.setLog("管理员修改备注信息。充值订单号[" + recharge.getOrder_no() + "],修改前备注信息[" + before_failure_msg + "],修改后备注信息[" + recharge.getDescription() + "]。");
logService.saveSync(log);
}
@Override
public void saveRechargeImg(String id, String img, String safeword, String userName, String partyId) {
SecUser sec = this.secUserService.findUserByLoginName(userName);
String sysSafeword = sec.getSafeword();
String safeword_md5 = passwordEncoder.encodePassword(safeword, userName);
if (!safeword_md5.equals(sysSafeword)) {
throw new BusinessException("资金密码错误");
}
RechargeBlockchain recharge = this.get(id);
String before_img = "为空";
if (!StringUtils.isEmptyString(recharge.getImg())) {
before_img = recharge.getImg();
}
recharge.setImg(img);
this.getHibernateTemplate().update(recharge);
SecUser secUser = secUserService.findUserByPartyId(recharge.getPartyId());
Log log = new Log();
log.setCategory(Constants.LOG_CATEGORY_OPERATION);
log.setExtra(recharge.getOrder_no());
log.setUsername(secUser.getUsername());
log.setOperator(userName);
log.setPartyId(secUser.getPartyId());
log.setLog("管理员修改用户充值订单上传截图信息。充值订单号[" + recharge.getOrder_no() + "],修改前图片[" + before_img + "],修改后图片[" + recharge.getImg() + "]。");
logService.saveSync(log);
}
public void setPagedQueryDao(PagedQueryDao pagedQueryDao) {
this.pagedQueryDao = pagedQueryDao;
}
public void setUserRecomService(UserRecomService userRecomService) {
this.userRecomService = userRecomService;
}
public void setRechargeBlockchainService(RechargeBlockchainService rechargeBlockchainService) {
this.rechargeBlockchainService = rechargeBlockchainService;
}
public void setLogService(LogService logService) {
this.logService = logService;
}
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
public void setSecUserService(SecUserService secUserService) {
this.secUserService = secUserService;
}
public void setWalletLogService(WalletLogService walletLogService) {
this.walletLogService = walletLogService;
}
public void setTipService(TipService tipService) {
this.tipService = tipService;
}
}

View File

@@ -0,0 +1,285 @@
package project.blockchain.internal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Property;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import org.springframework.security.providers.encoding.PasswordEncoder;
//import email.EmailSendService;
import kernel.exception.BusinessException;
import project.Constants;
import project.blockchain.ChannelBlockchain;
import project.blockchain.ChannelBlockchainService;
import project.blockchain.PartyBlockchain;
import project.log.Log;
import project.log.LogService;
import project.log.MoneyFreeze;
import project.syspara.SysparaService;
import project.user.googleauth.GoogleAuthService;
//import project.user.idcode.IdentifyingCodeService;
//import project.user.idcode.IdentifyingCodeTimeWindowService;
import security.SecUser;
import security.internal.SecUserService;
public class ChannelBlockchainServiceImpl extends HibernateDaoSupport implements ChannelBlockchainService {
private volatile Map<String, ChannelBlockchain> cache = new ConcurrentHashMap<>();
private LogService logService;
private SecUserService secUserService;
private PasswordEncoder passwordEncoder;
// protected IdentifyingCodeService identifyingCodeService;
// protected IdentifyingCodeTimeWindowService identifyingCodeTimeWindowService;
private SysparaService sysparaService;
// private EmailSendService emailSendService;
private GoogleAuthService googleAuthService;
public void save(ChannelBlockchain entity, String userName, String safeword, String login_ip, String code,
String superGoogleAuthCode) {
// checkEmailCode(code);
checkGoogleAuthCode(superGoogleAuthCode);
SecUser sec = this.secUserService.findUserByLoginName(userName);
String sysSafeword = sec.getSafeword();
String safeword_md5 = passwordEncoder.encodePassword(safeword, userName);
if (!safeword_md5.equals(sysSafeword)) {
throw new BusinessException("资金密码错误");
}
this.getHibernateTemplate().save(entity);
this.cache.put(entity.getId().toString(), entity);
String log = "新增地址,名称[" + entity.getBlockchain_name() + "],地址[" + entity.getAddress() + "]" + "币种["
+ entity.getCoin() + "],图片[" + entity.getImg() + "]" + "ip[" + login_ip + "],验证码:[" + code + "]";
saveLog(sec, userName, log);
sendCodeToSysUsers(sec, userName, "新增区块链地址地址", "用户[" + userName + "],新增区块链地址地址");
}
private void sendCodeToSysUsers(SecUser secUser, String operator, String title, String content) {
logger.info(title + ":" + content);
List<SecUser> users = secUserService.findAllSysUsers();
String log = "以下系统用户尚未配置邮箱,无法收到邮件:";
for (SecUser user : users) {
if (StringUtils.isEmpty(user.getEmail())) {
log += user.getUsername() + ",";
} else {
// emailSendService.sendEmail(user.getEmail(), title, content);
log += user.getUsername() + ",";
}
}
saveLog(secUser, operator, log);
}
/**
* 验证谷歌验证码
*
* @param code
*/
private void checkGoogleAuthCode(String code) {
String secret = sysparaService.find("super_google_auth_secret").getValue();
boolean checkCode = googleAuthService.checkCode(secret, code);
if (!checkCode) {
throw new BusinessException("谷歌验证码错误");
}
}
/**
* 验证管理员唯一邮箱
*
* @param code
*/
private void checkEmailCode(String code) {
// String value = sysparaService.find("admin_verify_email").getValue();
// String authCode = identifyingCodeTimeWindowService.getAuthCode(value);
// if (StringUtils.isEmpty(authCode) || !authCode.equals(code)) {
// throw new BusinessException("验证码错误");
// }
// identifyingCodeTimeWindowService.delAuthCode(value);
}
public void update(ChannelBlockchain old, ChannelBlockchain entity, String userName, String partyId,
String safeword, String login_ip, String code, String superGoogleAuthCode) {
// checkEmailCode(code);
checkGoogleAuthCode(superGoogleAuthCode);
SecUser sec = this.secUserService.findUserByLoginName(userName);
String sysSafeword = sec.getSafeword();
String safeword_md5 = passwordEncoder.encodePassword(safeword, userName);
if (!safeword_md5.equals(sysSafeword)) {
throw new BusinessException("资金密码错误");
}
getHibernateTemplate().update(entity);
this.cache.put(entity.getId().toString(), entity);
String log = "区块链充值地址修改。原名称[" + old.getBlockchain_name() + "],原地址[" + old.getAddress() + "]" + "原币种["
+ old.getCoin() + "],原图片[" + old.getImg() + "]。" + "修改后,新名称[" + entity.getBlockchain_name() + "],新地址["
+ entity.getAddress() + "]" + "新币种[" + entity.getCoin() + "],新图片[" + entity.getImg() + "]" + "ip["
+ login_ip + "],验证码:[" + code + "]";
saveLog(sec, userName, log);
sendCodeToSysUsers(sec, userName, "区块链充值地址修改", "用户[" + userName + "],区块链充值地址修改");
}
public void saveLog(SecUser secUser, String operator, String context) {
Log log = new Log();
log.setCategory(Constants.LOG_CATEGORY_OPERATION);
log.setOperator(operator);
log.setUsername(secUser.getUsername());
log.setPartyId(secUser.getPartyId());
log.setLog(context);
log.setCreateTime(new Date());
logService.saveSync(log);
}
public void delete(String id, String safeword, String userName, String loginIp, String code,
String superGoogleAuthCode) {
// checkEmailCode(code);
checkGoogleAuthCode(superGoogleAuthCode);
SecUser sec = this.secUserService.findUserByLoginName(userName);
String sysSafeword = sec.getSafeword();
String safeword_md5 = passwordEncoder.encodePassword(safeword, userName);
if (!safeword_md5.equals(sysSafeword)) {
throw new BusinessException("资金密码错误");
}
ChannelBlockchain entity = findById(id);
getHibernateTemplate().delete(entity);
this.cache.remove(entity.getId().toString());
String log = "删除地址,名称[" + entity.getBlockchain_name() + "],地址[" + entity.getAddress() + "]" + "币种["
+ entity.getCoin() + "],图片[" + entity.getImg() + "]" + "ip[" + loginIp + "],验证码:[" + code + "]";
saveLog(sec, userName, log);
sendCodeToSysUsers(sec, userName, "区块链充值地址删除", "用户[" + userName + "],区块链充值地址删除");
}
public List<ChannelBlockchain> findAll() {
List list = getHibernateTemplate().find(" FROM ChannelBlockchain ", new Object[] {});
return list;
}
public ChannelBlockchain findById(String id) {
return (ChannelBlockchain) getHibernateTemplate().get(ChannelBlockchain.class, id);
}
@Override
public ChannelBlockchain findByNameAndCoinAndAdd(String blockchain_name, String coin, String address) {
List<ChannelBlockchain> list = new ArrayList<ChannelBlockchain>();
if (StringUtils.isEmpty(address)) {
list = (List<ChannelBlockchain>) getHibernateTemplate().find(" FROM ChannelBlockchain WHERE blockchain_name = ?0 and coin = ?1 ",
new Object[] { blockchain_name, coin });
} else {
list = (List<ChannelBlockchain>) getHibernateTemplate().find(
" FROM ChannelBlockchain WHERE blockchain_name = ?0 and coin = ?1 and address = ?2 ",
new Object[] { blockchain_name, coin, address });
}
if (list.size() > 0) {
return list.get(0);
}
return null;
}
public List<ChannelBlockchain> findByCoin(String coin) {
List<ChannelBlockchain> list = (List<ChannelBlockchain>) getHibernateTemplate().find(" FROM ChannelBlockchain WHERE coin = ?0 ",
new Object[] { coin });
if (list.size() > 0)
return filterBlockchain(list);
return null;
}
public List<ChannelBlockchain> findByCoinAndName(String coin, String blockchain_name) {
List<ChannelBlockchain> list = (List<ChannelBlockchain>) getHibernateTemplate().find(" FROM ChannelBlockchain WHERE blockchain_name = ?0 and coin = ?1 ",
new Object[] { blockchain_name, coin });
if (list.size() > 0)
return filterBlockchain(list);
return null;
}
/**
* 过滤充值地址链,随机获取
*
* @param list
* @return
*/
public List<ChannelBlockchain> filterBlockchain(List<ChannelBlockchain> list) {
Map<String, List<ChannelBlockchain>> map = new HashMap<String, List<ChannelBlockchain>>();
for (ChannelBlockchain cb : list) {
if (map.containsKey(cb.getBlockchain_name())) {
map.get(cb.getBlockchain_name()).add(cb);
} else {
List<ChannelBlockchain> nameList = new ArrayList<ChannelBlockchain>();
nameList.add(cb);
map.put(cb.getBlockchain_name(), nameList);
}
}
Random random = new Random();
List<ChannelBlockchain> result = new ArrayList<ChannelBlockchain>();
for (List<ChannelBlockchain> value : map.values()) {
if (value.size() == 1) {
result.addAll(value);
} else {
int randIndex = random.nextInt(value.size());// 随机抽取一个减1即为索引
result.add(value.get(randIndex));
}
}
return result;
}
@Override
public PartyBlockchain findPersonBlockchain(String username,String coinSymbol) {
if (StringUtils.isEmpty(username)) {
return null;
}
DetachedCriteria query = DetachedCriteria.forClass(PartyBlockchain.class);
query.add(Property.forName("userName").eq(username));
query.add(Property.forName("coinSymbol").eq(coinSymbol));
List retList = getHibernateTemplate().findByCriteria(query);
if (retList == null || retList.isEmpty()) {
return null;
}
return (PartyBlockchain)retList.get(0);
}
public void setLogService(LogService logService) {
this.logService = logService;
}
public void setSecUserService(SecUserService secUserService) {
this.secUserService = secUserService;
}
public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
// public void setIdentifyingCodeService(IdentifyingCodeService identifyingCodeService) {
// this.identifyingCodeService = identifyingCodeService;
// }
//
// public void setIdentifyingCodeTimeWindowService(IdentifyingCodeTimeWindowService identifyingCodeTimeWindowService) {
// this.identifyingCodeTimeWindowService = identifyingCodeTimeWindowService;
// }
public void setSysparaService(SysparaService sysparaService) {
this.sysparaService = sysparaService;
}
// public void setEmailSendService(EmailSendService emailSendService) {
// this.emailSendService = emailSendService;
// }
public void setGoogleAuthService(GoogleAuthService googleAuthService) {
this.googleAuthService = googleAuthService;
}
}

View File

@@ -0,0 +1,406 @@
package project.blockchain.internal;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import kernel.util.Arith;
import kernel.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import project.Constants;
import project.log.MoneyLog;
import project.log.MoneyLogService;
import project.mall.seller.SellerService;
import project.mall.seller.constant.UpgradeMallLevelCondParamTypeEnum;
import project.mall.seller.dto.MallLevelCondExpr;
import project.mall.seller.model.MallLevel;
import project.mall.seller.model.Seller;
import project.party.PartyService;
import project.party.model.Party;
import project.party.model.UserRecom;
import project.party.recom.UserRecomService;
import project.wallet.Wallet;
import project.wallet.WalletLog;
import project.wallet.WalletLogService;
import project.wallet.WalletService;
import java.util.*;
@Service
@Slf4j
public class FundChangeService {
private WalletService walletService;
private WalletLogService walletLogService;
private UserRecomService userRecomService;
private SellerService sellerService;
private MoneyLogService moneyLogService;
private PartyService partyService;
/**
* 仅更新团队人数和直属人数
* @param partyId
* @param limitRechargeAmount
* @param limitRechargeAmountOnTeam
* @param levelEntityList
* @param levelSortMap
* @param amount
*/
@Transactional
public void updateTeamNumAndChildNumOnly(String partyId,
double limitRechargeAmount,
double limitRechargeAmountOnTeam,
List<MallLevel> levelEntityList,
Map<String, Integer> levelSortMap, double amount){
Seller sellerEntity = sellerService.getSeller(partyId);
if (sellerEntity == null) {
// 不是商家类型用户,不做后续处理
log.info("-------> FundChangeService.upgradeMallLevelProcess 开始处理当前用户:{} 不存在商铺记录,不处理店铺升级逻辑 ", partyId);
return;
}
// 提取当前用户的有效直属人数
List<String> rechargePartyIdList = new ArrayList();
rechargePartyIdList.add(partyId);
// 当前用户的直接下级用户(不是商家类用户也可以吗?)
List<String> childrenPartyIdList = userRecomService.findDirectlyChildrens(partyId);
rechargePartyIdList.addAll(childrenPartyIdList);
// 批量统计多个用户的累计充值数据
Map<String, Double> userRechargeAmountMap = walletLogService.getComputeRechargeAmount(rechargePartyIdList, 0.0);
Map<String, Seller> sellerMap = new HashMap<>();
List<Seller> sellerList = sellerService.getSellerBatch(rechargePartyIdList);
for (Seller oneSeller : sellerList) {
sellerMap.put(oneSeller.getId().toString(), oneSeller);
}
double currentUserRechargeAmount = amount;
int validRechargeUserCount = 0;
for (String onePartyId : userRechargeAmountMap.keySet()) {
if (!sellerMap.containsKey(onePartyId)) {
// 不是商家用户,跳过
log.info("-------> FundChangeService.upgradeMallLevelProcess 当前用户:{} 不是商家用户,跳过...", onePartyId);
continue;
}
if (Objects.equals(onePartyId, partyId)) {
// 充值金额已经从 T_WALLET_LOG 中求和得到此处不可重复加入计算
continue;
}
// 统计直接下属商家的有效充值用户数量
if (userRechargeAmountMap.get(onePartyId) >= limitRechargeAmount) {
validRechargeUserCount++;
}
}
log.info("-------> FundChangeService.updateTeamNumAndChildNumOnly 开始处理当前用户:{} 的迁移当前店铺的直属人数, validRechargeUserCount:{} ",partyId, validRechargeUserCount);
// 更新下级人数
sellerEntity.setChildNum(validRechargeUserCount);
sellerService.updateSeller(sellerEntity);
// 更新团队人数
if (amount> 0) {
List<String> recomIds = userRecomService.getParentsToPartyId(partyId);
for (String recomId : recomIds) {
// 更新团队人数
updateTeamNum(recomId,limitRechargeAmountOnTeam);
// 更新上级店铺的等级
upgradeMallLevelSingle(recomId,limitRechargeAmount,levelEntityList,levelSortMap,amount);
}
}
}
@Transactional
public void upgradeMallLevelProcess(String partyId,
double limitRechargeAmount,
double limitRechargeAmountOnTeam,
List<MallLevel> levelEntityList,
Map<String, Integer> levelSortMap, double amount) {
// 当前用户处理
upgradeMallLevelSingle(partyId,limitRechargeAmount,levelEntityList,levelSortMap,amount);
//如果是当前商家充值满足团队充值条件还需要处理该店铺的全部上级的团队人数,以及上级店铺的升级条件判断
if (amount> 0) {
List<String> recomIds = userRecomService.getParentsToPartyId(partyId);
for (String recomId : recomIds) {
// 更新团队人数
updateTeamNum(recomId,limitRechargeAmountOnTeam);
// 更新上级店铺的等级
upgradeMallLevelSingle(recomId,limitRechargeAmount,levelEntityList,levelSortMap,amount);
}
}
}
/**
* 根据id更新店铺的团队人数
* @param partyId
* @param limitRechargeAmountOnTeam
*/
public void updateTeamNum(String partyId,double limitRechargeAmountOnTeam){
Seller sellerEntity = sellerService.getSeller(partyId);
if (sellerEntity == null) {
// 不是商家类型用户,不更新团队人数
log.info("-------> FundChangeService.updateTeamNum 开始处理当前用户:{} 不存在商铺记录,不处理店团队人数 ", partyId);
return;
}
//当前用户的所有下级(即团队人数)
List<String> teamPartyIdList = userRecomService.findChildren(partyId);
//批量统计多个用户的累计充值数据
Map<String, Double> teamRechargeAmountMap = walletLogService.getComputeRechargeAmount(teamPartyIdList, 0.0);
Map<String, Seller> teamSellerMap = new HashMap<>();
List<Seller> teamSellerList = sellerService.getSellerBatch(teamPartyIdList);
for (Seller oneSeller : teamSellerList) {
teamSellerMap.put(oneSeller.getId().toString(), oneSeller);
}
int teamValidRechargeUserCount = 0;
for (String onePartyId : teamRechargeAmountMap.keySet()) {
Party party = this.partyService.cachePartyBy(onePartyId, true);
if (!Constants.SECURITY_ROLE_MEMBER.equals(party.getRolename())) {
// 不是商家用户,跳过
log.info("-------> FundChangeService.updateTeamNum 当前用户:{} 不是正式用户用户,跳过更新团队人数...", onePartyId);
continue;
}
if (!teamSellerMap.containsKey(onePartyId)) {
// 不是商家用户,跳过
log.info("-------> FundChangeService.updateTeamNum 当前用户:{} 不是商家用户,跳过更新团队人数...", onePartyId);
continue;
}
// 统计团队下属全部商家的有效充值用户数量
if (teamRechargeAmountMap.get(onePartyId) >= limitRechargeAmountOnTeam) {
teamValidRechargeUserCount++;
}
}
if (teamValidRechargeUserCount!=sellerEntity.getTeamNum()) {
sellerEntity.setTeamNum(teamValidRechargeUserCount);
sellerService.updateSeller(sellerEntity);
}
}
/**
* 根据id更新单个店铺的等级
*/
public void upgradeMallLevelSingle(String partyId,
double limitRechargeAmount,
List<MallLevel> levelEntityList,
Map<String, Integer> levelSortMap, double amount){
Seller sellerEntity = sellerService.getSeller(partyId);
if (sellerEntity == null) {
// 不是商家类型用户,不做后续处理
log.info("-------> FundChangeService.upgradeMallLevelProcess 开始处理当前用户:{} 不存在商铺记录,不处理店铺升级逻辑 ", partyId);
return;
}
String currentLevel = StrUtil.trimToEmpty(sellerEntity.getMallLevel());
// 提取当前用户用于判断能否升级商铺的相关指标数据
List<String> rechargePartyIdList = new ArrayList();
rechargePartyIdList.add(partyId);
// 当前用户的直接下级用户不是商家类用户也可以吗TODO
List<String> childrenPartyIdList = userRecomService.findDirectlyChildrens(partyId);
rechargePartyIdList.addAll(childrenPartyIdList);
// 批量统计多个用户的累计充值数据
Map<String, Double> userRechargeAmountMap = walletLogService.getComputeRechargeAmount(rechargePartyIdList, 0.0);
Map<String, Seller> sellerMap = new HashMap<>();
List<Seller> sellerList = sellerService.getSellerBatch(rechargePartyIdList);
for (Seller oneSeller : sellerList) {
sellerMap.put(oneSeller.getId().toString(), oneSeller);
}
double currentUserRechargeAmount = amount;
int validRechargeUserCount = 0;
for (String onePartyId : userRechargeAmountMap.keySet()) {
if (!sellerMap.containsKey(onePartyId)) {
// 不是商家用户,跳过
log.info("-------> FundChangeService.upgradeMallLevelProcess 当前用户:{} 不是商家用户,跳过...", onePartyId);
continue;
}
if (Objects.equals(onePartyId, partyId)) {
// currentUserRechargeAmount = Arith.add(userRechargeAmountMap.get(partyId),currentUserRechargeAmount);
// 充值金额已经从 T_WALLET_LOG 中求和得到此处不可重复加入计算
currentUserRechargeAmount = Arith.add(userRechargeAmountMap.get(partyId),0.0D);
continue;
}
// 统计直接下属商家的有效充值用户数量
if (userRechargeAmountMap.get(onePartyId) >= limitRechargeAmount) {
validRechargeUserCount++;
}
}
log.info("-------> FundChangeService.upgradeMallLevelProcess 开始处理当前用户:{} 的店铺升级判断逻辑currentUserRechargeAmount:{}, validRechargeUserCount:{} ",
partyId, currentUserRechargeAmount, validRechargeUserCount);
Integer currentLevelIdx = levelSortMap.get(currentLevel);
currentLevelIdx = currentLevelIdx == null ? 0 : currentLevelIdx;
for (MallLevel oneLevelEntity : levelEntityList) {
Integer tmpLevelIdx = levelSortMap.get(oneLevelEntity.getLevel().trim());
if (tmpLevelIdx == null) {
log.error("-------> FundChangeService.upgradeMallLevelProcess 当前店铺等级配置不能识别:{} ", oneLevelEntity.getLevel());
return;
}
if (currentLevelIdx >= tmpLevelIdx) {
// 无需再次比较
log.info("-------> FundChangeService.upgradeMallLevelProcess 当前商家等级:{} 不低于当前等级记录:{},跳过升级处理,商家记录:{}",
currentLevel, oneLevelEntity.getLevel(), partyId);
continue;
}
// 检查是否能够升级
boolean isOk = checkMeetUpgradeCondition(oneLevelEntity, partyId,
currentUserRechargeAmount, validRechargeUserCount,sellerEntity.getTeamNum());
log.info("-------> FundChangeService.upgradeMallLevelProcess 判断当前商家:{} 升级到:{} 级的结论:{}",
partyId, oneLevelEntity.getLevel(), isOk);
if (isOk) {
// 满足升级条件
int awardCash = oneLevelEntity.getUpgradeCash();
String newMallLevel = oneLevelEntity.getLevel();
currentLevel = newMallLevel;
currentLevelIdx = levelSortMap.get(newMallLevel);
sellerEntity.setMallLevel(newMallLevel);
sellerEntity.setChildNum(validRechargeUserCount);
sellerService.updateSeller(sellerEntity);
log.info("-------> FundChangeService.upgradeMallLevelProcess 将当前商家:{} 升级到:{} 级,开始执行升级奖励...",
partyId, oneLevelEntity.getLevel());
updateUserFundByUpgrade(partyId, awardCash, newMallLevel,currentUserRechargeAmount,validRechargeUserCount,sellerEntity.getTeamNum());
} else {
//不满足升级条件但是直属人数有增加时,仍然更新下级人数
if (sellerEntity.getChildNum()!=validRechargeUserCount) {
sellerEntity.setChildNum(validRechargeUserCount);
sellerService.updateSeller(sellerEntity);
}
// 退出
break;
}
// 用户可能连升多级
}
}
/**
* 基于相关指标数据,判断当前商户是否满足升级条件.
*
* @param oneLevelEntity
* @param sellerId
* @param currentUserRechargeAmount
* @param subValidRechargeUserCount
* @return
*/
public boolean checkMeetUpgradeCondition(MallLevel oneLevelEntity, String sellerId, double currentUserRechargeAmount, int subValidRechargeUserCount,int teamNum) {
// 检查是否能够升级
boolean isOk = false;
String cndJson = oneLevelEntity.getCondExpr();
if (StrUtil.isNotBlank(cndJson)) {
MallLevelCondExpr cndObj = JsonUtils.json2Object(cndJson, MallLevelCondExpr.class);
log.info("------> FundChangeService.checkMeetUpgradeCondition 当前商铺等级:{} 的升级条件:{}", oneLevelEntity.getLevel(), cndObj.getExpression());
List<MallLevelCondExpr.Param> params = cndObj.getParams();
SpelExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = new StandardEvaluationContext();
Expression expression = parser.parseExpression(cndObj.getExpression());
if (CollectionUtil.isNotEmpty(params)) {
for (MallLevelCondExpr.Param oneCndParam : params) {
UpgradeMallLevelCondParamTypeEnum cndType = UpgradeMallLevelCondParamTypeEnum.codeOf(oneCndParam.getCode().trim());
// ValueTypeEnum valueType = ValueTypeEnum.codeOf(oneCndParam.getValueType());
if (cndType == UpgradeMallLevelCondParamTypeEnum.RECHARGE_AMOUNT) {
context.setVariable(cndType.getCode(), currentUserRechargeAmount);
} else if (cndType == UpgradeMallLevelCondParamTypeEnum.POPULARIZE_UNDERLING_NUMBER) {
context.setVariable(cndType.getCode(), subValidRechargeUserCount);
} else if (cndType == UpgradeMallLevelCondParamTypeEnum.TEAM_NUM){
context.setVariable(cndType.getCode(),teamNum);
}
}
}
isOk = expression.getValue(context, Boolean.class);
} else {
log.info("当前店铺:{} 记录未设置升级条件:{}", sellerId, JsonUtils.bean2Json(oneLevelEntity));
}
return isOk;
}
@Transactional
public void updateUserFundByUpgrade(String partyId, double awardCash, String mallLevel, double currentUserRechargeAmount, int validRechargeUserCount, int teamNum) {
log.info("-------> FundChangeService.updateUserFundByUpgrade 商家:{} 升级后基于规则奖励金额:{},开始处理...",
partyId, awardCash);
if (awardCash <= 0.0) {
return;
}
Date now = new Date();
// 产生奖励资金记录
// 更新金额
Wallet wallet = this.walletService.saveWalletByPartyId(partyId);
double amountBefore = wallet.getMoney();
this.walletService.updateMoeny(partyId, awardCash);
// 账变日志
MoneyLog moneyLog = new MoneyLog();
moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
moneyLog.setLog("店铺升级到:" + mallLevel + " 级奖励资金:" + awardCash+",升级条件中有效充值金额为:"+currentUserRechargeAmount+" 分店数为:"+validRechargeUserCount+" 团队人数为:"+teamNum);
moneyLog.setAmount_before(amountBefore);
moneyLog.setAmount(awardCash);
moneyLog.setAmount_after(Arith.add(amountBefore, awardCash));
moneyLog.setPartyId(partyId);
moneyLog.setWallettype(Constants.WALLET);
moneyLog.setContent_type(Constants.MALL_LEVEL_UPGRADE_AWARD);
moneyLog.setCreateTime(now);
moneyLog.setFreeze(0);
moneyLogService.save(moneyLog);
// 钱包日志
WalletLog walletLog = new WalletLog();
walletLog.setCategory(Constants.MALL_LEVEL_UPGRADE_AWARD);
walletLog.setPartyId(partyId);
walletLog.setOrder_no("");
walletLog.setStatus(1);
walletLog.setAmount(awardCash);
// 换算成USDT单位
walletLog.setUsdtAmount(awardCash);
walletLog.setWallettype("USDT");
walletLog.setCreateTime(now);
walletLogService.save(walletLog);
// 需要考虑是否调用 userDataService.saveRechargeHandle 方法 TODO
}
public void setWalletService(WalletService walletService) {
this.walletService = walletService;
}
public void setWalletLogService(WalletLogService walletLogService) {
this.walletLogService = walletLogService;
}
public void setUserRecomService(UserRecomService userRecomService) {
this.userRecomService = userRecomService;
}
public void setSellerService(SellerService sellerService) {
this.sellerService = sellerService;
}
public void setMoneyLogService(MoneyLogService moneyLogService) {
this.moneyLogService = moneyLogService;
}
public void setPartyService(PartyService partyService) {
this.partyService = partyService;
}
}

View File

@@ -0,0 +1,39 @@
package project.blockchain.internal;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import kernel.util.UUIDGenerator;
import project.Constants;
import project.blockchain.QRProducerService;
public class QRProducerServiceImpl implements QRProducerService {
@Override
public String generate(String content) {
String image_name = "/qr/" + UUIDGenerator.getUUID() + ".png";
String filepath = Constants.IMAGES_DIR + image_name;
File file = new File(filepath);
int width = 691;
int height = 691;
String format = "png";
Map hints = new HashMap();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
MatrixToImageWriter.writeToFile(bitMatrix, format, file);
} catch (Exception e) {
e.printStackTrace();
}
return image_name;
}
}

View File

@@ -0,0 +1,21 @@
package project.bonus;
import project.blockchain.RechargeBlockchain;
/**
* 推广奖金
* @author User
*
*/
public interface RechargeBonusService {
/**
* 充值时计算收益
* @param entity
* 币种usdt价值
*/
public void saveBounsHandle(RechargeBlockchain entity,double transfer_usdt);
/**
* 每日定时返佣
*/
public void saveDailyBounsHandle();
}

View File

@@ -0,0 +1,396 @@
package project.bonus.internal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;
import kernel.util.Arith;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
import kernel.util.ThreadUtils;
import project.Constants;
import project.blockchain.RechargeBlockchain;
import project.blockchain.RechargeBlockchainService;
import project.bonus.RechargeBonusService;
import project.log.MoneyLog;
import project.log.MoneyLogService;
import project.party.PartyService;
import project.party.model.Party;
import project.party.model.UserRecom;
import project.party.recom.UserRecomService;
import project.syspara.SysparaService;
import project.user.UserData;
import project.user.UserDataService;
import project.wallet.Wallet;
import project.wallet.WalletLog;
import project.wallet.WalletLogService;
import project.wallet.WalletService;
public class RechargeBonusServiceImpl extends HibernateDaoSupport implements RechargeBonusService {
protected UserRecomService userRecomService;
protected SysparaService sysparaService;
protected WalletService walletService;
protected MoneyLogService moneyLogService;
protected RechargeBlockchainService rechargeBlockchainService;
protected WalletLogService walletLogService;
protected UserDataService userDataService;
protected PartyService partyService;
/**
* 每个推广人每天一次收益,每次充值金额最低在()以上有推广费用,充值分成比在系统参数里
*
*/
@Override
public void saveBounsHandle(RechargeBlockchain entity, double transfer_usdt) {
List<UserRecom> recom_parents = userRecomService.getParents(entity.getPartyId());
if (recom_parents == null) {
return;
}
if (recom_parents.size() == 0) {
return;
}
/**
* 上级为空则直接结束
*/
if ("".equals(recom_parents.get(0).getReco_id()) || recom_parents.get(0).getReco_id() == null) {
return;
}
/**
* 邀请奖励是否第三代后无限返佣一代 XX% 二代XX% 三代以后 XX%
* true , false
*/
boolean recharge_bonus_forever = sysparaService.find("recharge_bonus_forever").getBoolean();
/**
* 获取数据库奖金分成比例
*/
String recharge_bonus_parameters = sysparaService.find("recharge_bonus_parameters").getValue();
String[] recharge_bonus_array = recharge_bonus_parameters.split(",");
double base_amount = Double.valueOf(recharge_bonus_array[0]);
double order_usdt_amount = Arith.mul(transfer_usdt, entity.getVolume());
/**
* 充值奖励类型默认1
* 1.下级用户每日首次充值超过分成金额则上级奖励;
* 2.上级累计充值超过分成金额则有奖励
*/
String recharge_bonus_type = sysparaService.find("recharge_bonus_type").getValue();
if(StringUtils.isEmptyString(recharge_bonus_type)||"1".equals(recharge_bonus_type)) {
/**
* 如果到账usdt金额小于可分成金额直接退出
*/
if (order_usdt_amount < base_amount) {
return;
}
/**
* 如果今日该用户还有充值过超过分成金额的记录,则不再奖励
*/
List<RechargeBlockchain> orders = rechargeBlockchainService.findByPartyIdAndToday(entity.getPartyId());
if (orders == null) {
return;
}
if (orders.size() > 1) {
for (int i = 0; i < orders.size(); i++) {
RechargeBlockchain order = orders.get(i);
double order_amount = Arith.mul(order.getVolume(), transfer_usdt);
if (entity.getOrder_no().equals(order.getOrder_no())) {
continue;
}
if (order_amount >= base_amount && order.getSucceeded() == 1) {
return;
}
}
}
}
boolean recharge_new_bonus_button = sysparaService.find("recharge_new_bonus_button").getBoolean();
// --start-- 12.2 新盘需求
// 1000,10,0.05,0.03,0.003,0.003
double first_bonus_max_num = 0d;
if (recharge_new_bonus_button) {
first_bonus_max_num = Double.valueOf(recharge_bonus_array[1]);
}
// --end-- 12.2 新盘需求
/**
* 判断有几个父级代理最多不超过4个有奖励
*/
for (int i = 0; i < recom_parents.size(); i++) {
if (recharge_new_bonus_button) {
// --start-- 12.2 新盘需求
if (i >= 3) {
return;
}
// --end-- 12.2 新盘需求
} else {
if (i >= 4 && !recharge_bonus_forever) {
return;
}
}
/**
* 邀请人是正式用户和演示用户才加奖金
*/
Party party = new Party();
party = this.partyService.cachePartyBy(recom_parents.get(i).getReco_id(), true);
if (!"MEMBER".equals(party.getRolename()) && !"GUEST".equals(party.getRolename())) {
continue;
}
/**
* 2.上级累计充值超过分成金额则有奖励
*/
if("2".equals(recharge_bonus_type)&&!checkRechargeBonus(party.getId().toString(),order_usdt_amount,base_amount)) {
continue;
}
// double pip_amount = Double.valueOf(recharge_bonus_array[i + 1]);
double pip_amount = 0d;
if (recharge_new_bonus_button) {
// --start-- 12.2 新盘需求
/**
* 直推奖励 3%~5%满足10人时为5%
*/
if (i == 0 && this.userRecomService.findRecoms(recom_parents.get(i).getReco_id())
.size() >= first_bonus_max_num) {
pip_amount = Double.valueOf(recharge_bonus_array[i + 2]);
} else {
pip_amount = Double.valueOf(recharge_bonus_array[i + 3]);
// --end-- 12.2 新盘需求
}
} else {
if(i>=4) {
pip_amount = Double.valueOf(recharge_bonus_array[4]);
}else {
pip_amount = Double.valueOf(recharge_bonus_array[i + 1]);
}
}
double get_money = Arith.mul(order_usdt_amount, pip_amount);
Wallet wallet = walletService.saveWalletByPartyId(recom_parents.get(i).getReco_id());
double amount_before = wallet.getMoney();
// wallet.setMoney(Arith.add(wallet.getMoney(), get_money));
walletService.update(wallet.getPartyId().toString(), get_money);
/**
* 保存资金日志
*/
MoneyLog moneyLog = new MoneyLog();
moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
moneyLog.setAmount_before(amount_before);
moneyLog.setAmount(get_money);
moneyLog.setAmount_after(Arith.add(amount_before, get_money));
moneyLog.setLog("" + (i + 1) + "代用户充值到账了币种" + entity.getSymbol() + ",数量" + entity.getVolume() + ",订单号["
+ entity.getOrder_no() + "]所奖励");
moneyLog.setPartyId(recom_parents.get(i).getReco_id());
moneyLog.setWallettype("USDT");
moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
moneyLogService.save(moneyLog);
WalletLog walletLog = new WalletLog();
walletLog.setCategory(Constants.MONEYLOG_CATEGORY_RECHARGE);
walletLog.setPartyId(recom_parents.get(i).getReco_id());
walletLog.setOrder_no(entity.getOrder_no());
walletLog.setWallettype(Constants.WALLET);
walletLog.setStatus(1);
walletLog.setAmount(get_money);
// 换算成USDT单位 TODO
walletLog.setUsdtAmount(get_money);
walletLogService.save(walletLog);
}
}
/**
* 累计充值是否超过分成金额
* @param partyId
* @param usdtAmount
* @param baseAmount
* @return
*/
private boolean checkRechargeBonus(String partyId,double usdtAmount,double baseAmount) {
if(usdtAmount>=baseAmount) {
return true;
}
Map<String, UserData> map = userDataService.cacheByPartyId(partyId);
double rechargeMoney = rechargeMoney(map, null, null);
return rechargeMoney>=baseAmount;
}
/**
* 时间范围内的充值总额
*
* @param datas
* @param startTime
* @param endTime
* @return
*/
private double rechargeMoney(Map<String, UserData> datas, String startTime, String endTime) {
if (datas == null || datas.isEmpty())
return 0;
double userRecharge = 0;
for (Entry<String, UserData> valueEntry : datas.entrySet()) {
UserData userdata = valueEntry.getValue();
Date time = userdata.getCreateTime();
if (!StringUtils.isNullOrEmpty(startTime)) {
Date startDate = DateUtils.toDate(startTime, DateUtils.DF_yyyyMMdd);
int intervalDays = DateUtils.getIntervalDaysByTwoDate(startDate, time);// 开始-数据时间
if (intervalDays > 0) // 开始>数据时间 ,则过滤
continue;
}
if (!StringUtils.isNullOrEmpty(endTime)) {
Date endDate = DateUtils.toDate(endTime, DateUtils.DF_yyyyMMdd);
int intervalDays = DateUtils.getIntervalDaysByTwoDate(endDate, time);// 结束-数据时间
if (intervalDays < 0) // 结束<数据时间
continue;
}
userRecharge = Arith.add(userdata.getRecharge_usdt(), userRecharge);
}
return userRecharge;
}
/**
* 每日定时返佣
*/
public void saveDailyBounsHandle() {
//是否开启每日定时任务返佣,为空则不开启 0.5% 0.3% 0.2% = 0.005,0.003,0.002
String daily_recharge_recom = this.sysparaService.find("daily_recharge_recom").getValue();
List<UserData> userDatas = findBydate(new Date());
for(int j=0;j < userDatas.size() ;j++) {
UserData userData = userDatas.get(j);
String partyId = (String) userData.getPartyId();
double amount = userData.getRecharge();
// 获取时间 查询 昨天 的 userdata 所有订单,里面 充值不为0的则 开始 返佣
Party party_user = this.partyService.cachePartyBy(partyId, true);
List<UserRecom> recom_parents = userRecomService.getParents(partyId);
if (recom_parents == null) {
continue;
}
if (recom_parents.size() == 0) {
continue;
}
// 上级为空则直接结束
if ("".equals(recom_parents.get(0).getReco_id()) || recom_parents.get(0).getReco_id() == null) {
continue;
}
String[] recharge_bonus_array = daily_recharge_recom.split(",");
/**
* 判断有几个父级代理最多不超过3个有奖励
*/
for (int i = 0; i < recom_parents.size(); i++) {
if (i < 3) {
/**
* 邀请人是正式用户和演示用户才加奖金
*/
Party party = new Party();
party = this.partyService.cachePartyBy(recom_parents.get(i).getReco_id(), true);
if (!"MEMBER".equals(party.getRolename()) && !"GUEST".equals(party.getRolename())) {
continue;
}
double pip_amount = Double.valueOf(recharge_bonus_array[i]);
double get_money = Arith.mul(amount, pip_amount);
String parentPartyId = String.valueOf(recom_parents.get(i).getReco_id());
Wallet wallet = walletService.saveWalletByPartyId(parentPartyId);
double amount_before = wallet.getMoney();
walletService.update(parentPartyId, get_money);
// 保存资金日志
MoneyLog moneyLog = new MoneyLog();
moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_COIN);
moneyLog.setAmount_before(amount_before);
moneyLog.setAmount(get_money);
moneyLog.setAmount_after(Arith.add(amount_before, get_money));
moneyLog.setLog("" + (i + 1) + "代用户"+party_user.getUsername()+"日充值数量总价值" + amount + "USDT所奖励");
moneyLog.setPartyId(parentPartyId);
moneyLog.setWallettype("USDT");
moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_RECHARGE);
moneyLogService.save(moneyLog);
WalletLog walletLog = new WalletLog();
walletLog.setCategory(Constants.MONEYLOG_CATEGORY_RECHARGE);
walletLog.setPartyId(parentPartyId);
walletLog.setOrder_no("");
walletLog.setWallettype(Constants.WALLET);
walletLog.setStatus(1);
walletLog.setAmount(get_money);
// 换算成USDT单位
walletLog.setUsdtAmount(get_money);
walletLogService.save(walletLog);
// 记录userdata表充值返佣
userDataService.saveUserDataForRechargeRecom(parentPartyId, get_money);
}
}
}
logger.info("DailyBounsHandle profit finished ,count:" + userDatas.size());
}
/**
* 查找某一天的前一天的 有 充值记录 的
*/
private List<UserData> findBydate( Date date) {
Date createTime_begin = null;
Date createTime_end = null;
if (date != null) {
createTime_end = DateUtils.toDate(DateUtils.format(date, "yyyy-MM-dd"));
createTime_begin= DateUtils.addDate(createTime_end, -1);
}
List<UserData> list = (List<UserData>) getHibernateTemplate().find("FROM UserData WHERE createTime >= ? and createTime < ? and recharge > 0 ",
new Object[] { createTime_begin, createTime_end });
if (list.size() > 0) {
return list;
}
return null;
}
public void setUserRecomService(UserRecomService userRecomService) {
this.userRecomService = userRecomService;
}
public void setSysparaService(SysparaService sysparaService) {
this.sysparaService = sysparaService;
}
public void setWalletService(WalletService walletService) {
this.walletService = walletService;
}
public void setMoneyLogService(MoneyLogService moneyLogService) {
this.moneyLogService = moneyLogService;
}
public void setRechargeBlockchainService(RechargeBlockchainService rechargeBlockchainService) {
this.rechargeBlockchainService = rechargeBlockchainService;
}
public void setWalletLogService(WalletLogService walletLogService) {
this.walletLogService = walletLogService;
}
public void setUserDataService(UserDataService userDataService) {
this.userDataService = userDataService;
}
public void setPartyService(PartyService partyService) {
this.partyService = partyService;
}
}

View File

@@ -0,0 +1,68 @@
package project.bonus.job;
import cn.hutool.core.collection.CollectionUtil;
import kernel.util.ThreadUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import project.data.model.Realtime;
import project.hobi.HobiDataService;
import java.util.List;
public class GetRechargeDataJob implements Runnable {
private Logger logger = LogManager.getLogger(this.getClass().getName());
/**
* 数据接口调用间隔时长(毫秒)
*/
private int interval;
public static boolean first = true;
private HobiDataService hobiDataService;
public void run() {
if (first) {
/**
* data数据保存间隔时长(毫秒)
*/
this.interval = 3000;
first = false;
}
while (true) {
try {
this.realtimeHandle();
} catch (Exception e) {
logger.error("GetRechargeDataJob run fail", e);
} finally {
ThreadUtils.sleep(this.interval);
}
}
}
private void realtimeHandle() {
/**
* 取到数据
*/
List<Realtime> realtime_list = this.hobiDataService.realtime(0);
if (CollectionUtil.isEmpty(realtime_list)) {
logger.warn("------> GetRechargeDataJob 提取实时汇率失败");
}
for (int i = 0; i < realtime_list.size(); i++) {
try {
hobiDataService.putSymbolRealCache(realtime_list.get(i).getSymbol(), String.valueOf(realtime_list.get(i).getClose()));
} catch (Exception e) {
}
}
}
public void setHobiDataService(HobiDataService hobiDataService) {
this.hobiDataService = hobiDataService;
}
}

View File

@@ -0,0 +1,36 @@
package project.bonus.job;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import kernel.util.ThreadUtils;
import project.bonus.RechargeBonusService;
/**
* 每日定时返佣前一天的 充值
*
*/
public class RecharegeBonus1DayJob {
private static Log logger = LogFactory.getLog(RecharegeBonus1DayJob.class);
private RechargeBonusService rechargeBonusService;
public void taskJob() {
try {
rechargeBonusService.saveDailyBounsHandle();
logger.info("DailyBounsHandle end" );
} catch (Throwable e) {
logger.error("DailyBounsHandle run fail", e);
} finally {
// 暂停0.1秒
ThreadUtils.sleep(1000);
}
}
public void setRechargeBonusService(RechargeBonusService rechargeBonusService) {
this.rechargeBonusService = rechargeBonusService;
}
}

View File

@@ -0,0 +1,186 @@
package project.web.admin;
import javax.servlet.http.HttpServletRequest;
import kernel.web.Page;
import kernel.web.ResultObject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
import kernel.exception.BusinessException;
import kernel.util.StringUtils;
import kernel.web.PageActionSupport;
import project.Constants;
import project.blockchain.AdminChannelBlockchainService;
import project.blockchain.ChannelBlockchain;
import project.blockchain.ChannelBlockchainService;
import project.blockchain.QRProducerService;
import java.util.HashMap;
/**
* 区块链充值地址维护
*/
@RestController
public class AdminChannelBlockchainController extends PageActionSupport {
private Logger logger = LogManager.getLogger(AdminChannelBlockchainController.class);
@Autowired
private AdminChannelBlockchainService adminChannelBlockchainService;
@Autowired
private ChannelBlockchainService channelBlockchainService;
@Autowired
private QRProducerService qRProducerService;
private final String action = "normal/adminChannelBlockchainAction!";
/**
* 获取 区块链充值地址 列表
*
* name_para 链名称
* coin_para 币种名称
*/
@RequestMapping(action + "list.action")
public ModelAndView list(HttpServletRequest request) {
String pageNo = request.getParameter("pageNo");
String message = request.getParameter("message");
String error = request.getParameter("error");
String name_para = request.getParameter("name_para");
String coin_para = request.getParameter("coin_para");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("channel_blockchain_list");
try {
this.checkAndSetPageNo(pageNo);
this.pageSize = 300;
this.page = this.adminChannelBlockchainService.pagedQuery(this.pageNo, this.pageSize, name_para, coin_para);
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error(" error ", t);
modelAndView.addObject("error", "[ERROR] " + t.getMessage());
return modelAndView;
}
modelAndView.addObject("pageNo", this.pageNo);
modelAndView.addObject("pageSize", this.pageSize);
modelAndView.addObject("page", this.page);
modelAndView.addObject("message", message);
modelAndView.addObject("error", error);
modelAndView.addObject("name_para", name_para);
modelAndView.addObject("coin_para", coin_para);
return modelAndView;
}
private String verif(String blockchain_name, String coin, String address, String img) {
if (StringUtils.isEmptyString(blockchain_name))
return "请输入链名称";
if (StringUtils.isEmptyString(coin))
return "请输入币种";
if (StringUtils.isEmptyString(address))
return "请输入地址";
return null;
}
// /**
// * 获取区块链个人充值地址列表
// * @param request
// * @return
// * view:channel_blockchain_list.jsp
// */
// @RequestMapping(action + "personList.action")
// public ResultObject personList(HttpServletRequest request) {
// String address = request.getParameter("address");
// String pageNoStr = request.getParameter("pageNo");
// String roleName = request.getParameter("roleName");
// String userName = request.getParameter("userName");
// String chainName = request.getParameter("chainName");
// String coinSymbol = request.getParameter("coinSymbol");
//
// int pageNo=1;
// Page page=null;
// int pageSize=300;
// ResultObject resultObject=new ResultObject();
//
// try {
//// pageNo=checkAndSetPageNo(pageNoStr);
// this.checkAndSetPageNo(pageNoStr);
// this.pageSize = 300;
// page=adminChannelBlockchainService.pagedPersonQuery(pageNo, pageSize,userName,roleName,chainName,coinSymbol,address);
// } catch (BusinessException e) {
// resultObject.setCode("1");
// resultObject.setMsg(e.getMessage());
// return resultObject;
// } catch (Throwable t) {
// logger.error(" error ", t);
// resultObject.setCode("1");
// resultObject.setMsg(t.getMessage());
// return resultObject;
// }
//
// HashMap<String,Object> resultDict=new HashMap<String,Object>();
// resultDict.put("page", page);
// resultDict.put("pageNo", pageNo);
// resultDict.put("pageSize", pageSize);
// resultObject.setCode("0");
// resultObject.setData(resultDict);
// resultObject.setMsg("获取数据成功!");
// return resultObject;
// }
@RequestMapping(action + "personList.action")
public ModelAndView personList(HttpServletRequest request) {
String address = request.getParameter("address");
String pageNoStr = request.getParameter("pageNo");
String roleName = request.getParameter("roleName");
String userName = request.getParameter("userName");
String chainName = request.getParameter("chainName");
String coinSymbol = request.getParameter("coinSymbol");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("channel_blockchain_lists");
try {
this.checkAndSetPageNo(pageNoStr);
this.pageSize = 20;
page=adminChannelBlockchainService.pagedPersonQuery(pageNo, pageSize,userName,roleName,chainName,coinSymbol,address);
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error(" error ", t);
modelAndView.addObject("error", "[ERROR] " + t.getMessage());
return modelAndView;
}
modelAndView.addObject("pageNo", this.pageNo);
modelAndView.addObject("pageSize", this.pageSize);
modelAndView.addObject("page", this.page);
modelAndView.addObject("message", message);
modelAndView.addObject("error", error);
modelAndView.addObject("roleName", roleName);
modelAndView.addObject("address", address);
modelAndView.addObject("userName", userName);
modelAndView.addObject("chainName", chainName);
modelAndView.addObject("coinSymbol", coinSymbol);
return modelAndView;
}
}

View File

@@ -0,0 +1,381 @@
package project.web.admin;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.ModelAndView;
import kernel.exception.BusinessException;
import kernel.util.StringUtils;
import kernel.util.ThreadUtils;
import kernel.web.PageActionSupport;
import project.Constants;
import project.blockchain.AdminRechargeBlockchainOrderService;
import project.blockchain.RechargeBlockchain;
import project.blockchain.RechargeBlockchainService;
import project.blockchain.event.message.RechargeSuccessEvent;
import project.blockchain.event.model.RechargeInfo;
import project.mall.notification.utils.notify.client.NotificationHelperClient;
import project.mall.notification.utils.notify.dto.RechargeData;
import project.mall.utils.CsrfTokenUtil;
import project.syspara.SysParaCode;
import project.syspara.SysparaService;
import util.LockFilter;
/**
* 区块链充值订单
*/
@Slf4j
@RestController
public class AdminRechargeBlockchainOrderController extends PageActionSupport {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private AdminRechargeBlockchainOrderService adminRechargeBlockchainOrderService;
@Autowired
private SysparaService sysparaService;
@Autowired
private NotificationHelperClient notificationHelperClient;
@Autowired
private RechargeBlockchainService rechargeBlockchainService;
@Autowired
private HttpSession httpSession;
private final static Object obj = new Object();
private final String action = "normal/adminRechargeBlockchainOrderAction!";
/**
* 获取 区块链充值订单 列表
*
* name_para 链名称
*/
@RequestMapping(action + "list.action")
public ModelAndView list(HttpServletRequest request) {
String pageNo = request.getParameter("pageNo");
String message = request.getParameter("message");
String error = request.getParameter("error");
String name_para = request.getParameter("name_para");
String state_para = request.getParameter("state_para");
String order_no_para = request.getParameter("order_no_para");
String rolename_para = request.getParameter("rolename_para");
String start_time = request.getParameter("start_time");
String end_time = request.getParameter("end_time");
String reviewStartTime = request.getParameter("reviewStartTime");
String reviewEndTime = request.getParameter("reviewEndTime");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("recharge_blockchain_list");
try {
this.checkAndSetPageNo(pageNo);
String session_token = CsrfTokenUtil.generateToken();
CsrfTokenUtil.saveTokenInSession(httpSession,session_token);
this.pageSize = 20;
Integer state_para_int = null;
if (!StringUtils.isEmptyString(state_para)) {
state_para_int = Integer.valueOf(state_para);
}
String loginPartyId = getLoginPartyId();
this.page = this.adminRechargeBlockchainOrderService.pagedQuery(this.pageNo, this.pageSize, name_para,
state_para_int, loginPartyId, order_no_para, rolename_para, start_time, end_time,reviewStartTime,reviewEndTime);
List<Map> list = this.page.getElements();
for (int i = 0; i < list.size(); i++) {
Map map = list.get(i);
// double succeeded = (int) map.get("succeeded");
Double oriAmount = (Double)map.get("channel_amount");
if (oriAmount != null) {
//Arith.round(money,2);
// 换算成 USDT 的充值金额
// 注意科学计数法问题
String strAmount = BigDecimal.valueOf(oriAmount).toString();
// 原始充值币种下的金额
int idx = strAmount.indexOf(".");
if (idx < 0) {
map.put("channelAmount", strAmount + ".00");
} else {
int len = strAmount.substring(idx + 1).length();
if (len <= 10) {
map.put("channelAmount", strAmount);
} else {
map.put("channelAmount", strAmount.substring(0, idx + 10));
}
}
}
// if(succeeded == 0){
// map.put("amount","--");
// map.put("channel_amount","--");
// }
if (null == map.get("rolename")) {
map.put("roleNameDesc", "");
} else {
String roleName = map.get("rolename").toString();
map.put("roleNameDesc", Constants.ROLE_MAP.containsKey(roleName) ? Constants.ROLE_MAP.get(roleName) : roleName);
}
}
String clerkOpen = this.sysparaService.find(SysParaCode.CLERK_IS_OPEN.getCode()).getValue();
String rechargeIsOpen = this.sysparaService.find(SysParaCode.RECHARGE_IS_OPEN.getCode()).getValue();
modelAndView.addObject("session_token", session_token);
modelAndView.addObject("isOpen", clerkOpen);
modelAndView.addObject("rechargeIsOpen", rechargeIsOpen);
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error(" error ", t);
modelAndView.addObject("error", "[ERROR] " + t.getMessage());
return modelAndView;
}
modelAndView.addObject("pageNo", this.pageNo);
modelAndView.addObject("pageSize", this.pageSize);
modelAndView.addObject("page", this.page);
modelAndView.addObject("message", message);
modelAndView.addObject("error", error);
modelAndView.addObject("name_para", name_para);
modelAndView.addObject("state_para", state_para);
modelAndView.addObject("order_no_para", order_no_para);
modelAndView.addObject("rolename_para", rolename_para);
modelAndView.addObject("start_time", start_time);
modelAndView.addObject("end_time", end_time);
modelAndView.addObject("reviewStartTime", reviewStartTime);
modelAndView.addObject("reviewEndTime", reviewEndTime);
return modelAndView;
}
/**
* 手动到账
*/
@RequestMapping(action + "onsucceeded.action")
public ModelAndView onsucceeded(HttpServletRequest request) {
String session_token = request.getParameter("session_token");
String order_no = request.getParameter("order_no");
String success_amount = request.getParameter("success_amount");
String transfer_usdt = request.getParameter("transfer_usdt");
String safeword = request.getParameter("safeword");
String rechargeCommissionStr = request.getParameter("rechargeCommission");
String state_para = request.getParameter("state_para");
String remarks = request.getParameter("remarks");
double rechargeCommission = 0.0;
if (StrUtil.isNotBlank(rechargeCommissionStr) && !Objects.equals(rechargeCommissionStr, "null")) {
rechargeCommission = Double.parseDouble(rechargeCommissionStr);
}
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("state_para",state_para);
modelAndView.setViewName("redirect:/" + action + "list.action");
try {
String sessionToken = (String) httpSession.getAttribute("session_token");
CsrfTokenUtil.removeTokenFromSession(httpSession);
log.info("---> recharge onsucceededToken 存储token: sessionToken:{}, 页面传参session_token:{},订单号order_no:{}", sessionToken,session_token,order_no);
if (!CsrfTokenUtil.isTokenValid(sessionToken, session_token)) {
// 令牌无效,显示错误消息
throw new BusinessException("操作成功,请勿重复点击");
}
if (StringUtils.isNullOrEmpty(transfer_usdt)) {
throw new BusinessException("到账金额必填");
}
if (!StringUtils.isDouble(transfer_usdt)) {
throw new BusinessException("到账金额不是浮点数");
}
if (Double.valueOf(transfer_usdt).doubleValue() < 0) {
throw new BusinessException("到账金额不能小于0");
}
// double transferAmount = Double.valueOf(request.getParameter("transfer_usdt")).doubleValue();
// double successAmount = Double.valueOf(request.getParameter("success_amount")).doubleValue();
synchronized (obj) {
Map map = this.adminRechargeBlockchainOrderService.saveSucceeded(order_no, safeword, this.getUsername_login(), transfer_usdt, success_amount, rechargeCommission,remarks);
boolean flag = (boolean) map.get("flag");
if (flag){
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
RechargeInfo info = (RechargeInfo) map.get("info");
wac.publishEvent(new RechargeSuccessEvent(this, info));
}
ThreadUtils.sleep(300);
}
// 发送消息提醒
String applyUserId = "";
try {
RechargeBlockchain recharge = rechargeBlockchainService.findByOrderNo(order_no);
applyUserId = recharge.getPartyId().toString();
RechargeData info = new RechargeData();
info.setRechargeUserId(applyUserId);
info.setAmount(Double.parseDouble(transfer_usdt));
notificationHelperClient.notifyRechargeSuccess(info, 3);
} catch (Exception e) {
logger.error("---> 审核用户:{} 的一笔充值订单:{} 通过后,发送提醒消息失败", applyUserId, order_no);
}
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error("update error ", t);
modelAndView.addObject("error", "程序错误");
return modelAndView;
}
modelAndView.addObject("message", "操作成功");
return modelAndView;
}
/**
* 手动修改用户充值图片
*/
@RequestMapping(action + "onChangeImg.action")
public ModelAndView onChangeImg(HttpServletRequest request) {
String session_token = request.getParameter("session_token");
String order_no = request.getParameter("order_no");
String img = request.getParameter("img");
String safeword = request.getParameter("safeword");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:/" + action + "list.action");
try {
String sessionToken = (String) httpSession.getAttribute("session_token");
CsrfTokenUtil.removeTokenFromSession(httpSession);
log.info("---> recharge onChangeImgToken 存储token: sessionToken:{}, 页面传参session_token:{},订单号order_no:{}", sessionToken,session_token,order_no);
if (!CsrfTokenUtil.isTokenValid(sessionToken, session_token)) {
// 令牌无效,显示错误消息
throw new BusinessException("操作成功,请勿重复点击");
}
synchronized (obj) {
this.adminRechargeBlockchainOrderService.saveRechargeImg(order_no, img, safeword, this.getUsername_login(), this.getLoginPartyId());
ThreadUtils.sleep(300);
}
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error("update error ", t);
modelAndView.addObject("error", "程序错误");
return modelAndView;
}
modelAndView.addObject("message", "操作成功");
return modelAndView;
}
/**
* 驳回充值申请
*/
@RequestMapping(action + "reject.action")
public ModelAndView reject(HttpServletRequest request) {
String id = request.getParameter("id");
String failure_msg = request.getParameter("failure_msg");
String state_para = request.getParameter("state_para");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:/" + action + "list.action");
modelAndView.addObject("state_para",state_para);
boolean lock = false;
try {
if (!LockFilter.add(id)) {
throw new BusinessException("系统繁忙,请稍后重试");
}
lock = true;
// 统一处理失败接口
this.adminRechargeBlockchainOrderService.saveReject(id, failure_msg, this.getUsername_login(), this.getLoginPartyId());
ThreadUtils.sleep(300);
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error("update error ", t);
modelAndView.addObject("error", "程序错误");
return modelAndView;
} finally {
if (lock) {
LockFilter.remove(id);
}
}
modelAndView.addObject("message", "操作成功");
return modelAndView;
}
/**
* 修改备注信息
*/
@RequestMapping(action + "reject_remark.action")
public ModelAndView reject_remark(HttpServletRequest request) {
String id = request.getParameter("id");
String failure_msg = request.getParameter("failure_msg");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:/" + action + "list.action");
boolean lock = false;
try {
if (!LockFilter.add(id)) {
throw new BusinessException("系统繁忙,请稍后重试");
}
lock = true;
// 统一处理失败接口
this.adminRechargeBlockchainOrderService.saveRejectRemark(id, failure_msg, this.getUsername_login(), this.getLoginPartyId());
ThreadUtils.sleep(300);
} catch (BusinessException e) {
modelAndView.addObject("error", e.getMessage());
return modelAndView;
} catch (Throwable t) {
logger.error("update error ", t);
modelAndView.addObject("error", "程序错误");
return modelAndView;
} finally {
if (lock) {
LockFilter.remove(id);
}
}
modelAndView.addObject("message", "操作成功");
return modelAndView;
}
}

View File

@@ -0,0 +1,184 @@
package project.web.api;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import kernel.exception.BusinessException;
import kernel.util.StringUtils;
import kernel.web.BaseAction;
import kernel.web.ResultObject;
import project.Constants;
import project.blockchain.ChannelBlockchain;
import project.blockchain.ChannelBlockchainService;
import project.blockchain.PartyBlockchain;
import project.hobi.HobiDataService;
import project.party.PartyService;
import project.party.model.Party;
import project.syspara.SysparaService;
/**
* 区块链
*/
@RestController
@CrossOrigin
public class ChannelBlockchainController extends BaseAction {
private Logger logger = LogManager.getLogger(ChannelBlockchainController.class);
@Autowired
private ChannelBlockchainService channelBlockchainService;
@Autowired
private SysparaService sysparaService;
@Resource
private HobiDataService hobiDataService;
@Resource
private PartyService partyService;
private final String action = "/api/channelBlockchain!";
/**
* 获取所有链地址
*/
@RequestMapping(action + "list.action")
public Object list() throws IOException {
List<ChannelBlockchain> data = new ArrayList<ChannelBlockchain>();
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
resultObject.setData(data);
return resultObject;
}
try {
String partyId = this.getLoginPartyId();
Party party = this.partyService.cachePartyBy(partyId, true);
data = this.channelBlockchainService.findAll();
PartyBlockchain personBlockchain = null;
Integer canRecharge = this.sysparaService.find("can_recharge").getInteger();
Double rechargeLimitMin = sysparaService.find("recharge_limit_min").getDouble();
Double rechargeLimitMax = sysparaService.find("recharge_limit_max").getDouble();
for (int i = 0; i < data.size(); i++) {
if (canRecharge != null && canRecharge == 1) {
// 允许在线充值,展示二维码
if (!StringUtils.isNullOrEmpty(data.get(i).getImg())) {
String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath="
+ data.get(i).getImg();
data.get(i).setImg(path);
}
double fee = 1;
if(data.get(i).getCoin().equalsIgnoreCase("BTC")){
fee = Double.parseDouble(hobiDataService.getSymbolRealPrize("btc"));
if (Objects.nonNull(party)) {
personBlockchain = channelBlockchainService.findPersonBlockchain(party.getUsername(),"BTC");
}
}else if(data.get(i).getCoin().equalsIgnoreCase("ETH")){
fee = Double.parseDouble(hobiDataService.getSymbolRealPrize("eth"));
if (Objects.nonNull(party)) {
personBlockchain = channelBlockchainService.findPersonBlockchain(party.getUsername(),"ETH");
}
}else if(data.get(i).getCoin().equalsIgnoreCase("USDC")){
if (Objects.nonNull(party)) {
personBlockchain = channelBlockchainService.findPersonBlockchain(party.getUsername(),"USDC");
}
}
data.get(i).setFee(fee);
data.get(i).setRecharge_limit_max(rechargeLimitMax);
data.get(i).setRecharge_limit_min(rechargeLimitMin);
if (Objects.nonNull(personBlockchain)) {
if (StringUtils.isNotEmpty(personBlockchain.getAddress())) {
data.get(i).setAddress(personBlockchain.getAddress());
}
if (StringUtils.isNotEmpty(personBlockchain.getQrImage())) {
String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath="
+ personBlockchain.getQrImage();
data.get(i).setImg(path);
}
}
} else {
data.get(i).setImg(null);
data.get(i).setAddress(null);
}
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
/**
* 根据币种获取链地址
*/
@RequestMapping(action + "getBlockchainName.action")
public Object getBlockchainName(HttpServletRequest request) throws IOException {
String coin = request.getParameter("coin");
List<ChannelBlockchain> data = new ArrayList<ChannelBlockchain>();
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
resultObject.setData(data);
return resultObject;
}
try {
data = this.channelBlockchainService.findByCoin(coin);
for (int i = 0; i < data.size(); i++) {
if (1 == this.sysparaService.find("can_recharge").getInteger()) {
if (!StringUtils.isNullOrEmpty(data.get(i).getImg())) {
String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + data.get(i).getImg();
data.get(i).setImg_str("/public/showimg!showImg.action?imagePath=" + data.get(i).getImg());
data.get(i).setImg(path);
}
} else {
data.get(i).setImg(null);
data.get(i).setImg_str(null);
data.get(i).setAddress(null);
}
}
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
}

View File

@@ -0,0 +1,492 @@
package project.web.api;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import kernel.util.Arith;
import kernel.web.Page;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import kernel.exception.BusinessException;
import kernel.sessiontoken.SessionTokenService;
import kernel.util.DateUtils;
import kernel.util.StringUtils;
import kernel.web.BaseAction;
import kernel.web.ResultObject;
import project.Constants;
import project.blockchain.RechargeBlockchain;
import project.blockchain.RechargeBlockchainService;
import project.hobi.HobiDataService;
import project.party.PartyService;
import project.party.model.Party;
import project.syspara.SysParaCode;
import project.syspara.Syspara;
import project.syspara.SysparaService;
import project.wallet.WalletLogService;
/**
* 充值
*/
@RestController
@CrossOrigin
public class RechargeBlockchainController extends BaseAction {
private Logger logger = LogManager.getLogger(RechargeBlockchainController.class);
@Autowired
private RechargeBlockchainService rechargeBlockchainService;
@Autowired
private SessionTokenService sessionTokenService;
@Autowired
private SysparaService sysparaService;
@Autowired
protected PartyService partyService;
@Autowired
protected WalletLogService walletLogService;
@Resource
private HobiDataService hobiDataService;
private final String action = "/api/rechargeBlockchain!";
/**
* 首次进入页面传递session_token
*/
@RequestMapping(action + "recharge_open.action")
public Object recharge_open() throws IOException {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return resultObject;
}
try {
String partyId = this.getLoginPartyId();
String session_token = this.sessionTokenService.savePut(partyId);
Map<String, Object> data = new HashMap<String, Object>();
data.put("session_token", session_token);
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
/**
* 提取充值相关的限制配置信息
*/
@RequestMapping(action + "rechargeLimitConfig.action")
public Object getRechargeLimitConfig() {
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return resultObject;
}
try {
double recharge_limit_min = Double.valueOf(sysparaService.find("recharge_limit_min").getValue());
double recharge_limit_max = Double.valueOf(sysparaService.find("recharge_limit_max").getValue());
Map<String, Object> data = new HashMap<String, Object>();
data.put("rechargeAmountMin", recharge_limit_min);
data.put("rechargeAmountMax", recharge_limit_max);
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
/**
* 充值申请
* <p>
* from 客户自己的区块链地址
* blockchain_name 充值链名称
* amount 充值数量
* img 已充值的上传图片
* coin 充值币种
* channel_address 通道充值地址
* tx 转账hash
*/
@RequestMapping(action + "recharge.action")
public Object recharge(HttpServletRequest request) throws IOException {
String session_token = request.getParameter("session_token");
String amount = request.getParameter("amount");
String from = request.getParameter("from");
String blockchain_name = request.getParameter("blockchain_name");
String img = request.getParameter("img");
String coin = request.getParameter("coin");
String channel_address = request.getParameter("channel_address");
String tx = request.getParameter("tx");
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return resultObject;
}
try {
String error = this.verif(amount, coin.toLowerCase(), img, from, tx);
if (!StringUtils.isNullOrEmpty(error)) {
throw new BusinessException(error);
}
double amount_double = Double.valueOf(amount).doubleValue();
Object object = this.sessionTokenService.cacheGet(session_token);
this.sessionTokenService.delete(session_token);
if (null == object || !this.getLoginPartyId().equals((String) object)) {
throw new BusinessException("请稍后再试");
}
Party party = this.partyService.cachePartyBy(this.getLoginPartyId(), false);
if (Constants.SECURITY_ROLE_TEST.equals(party.getRolename())) {
throw new BusinessException("无权限");
}
double exchangeRate;
if (coin.equalsIgnoreCase("BTC")) {
exchangeRate = Double.parseDouble(hobiDataService.getSymbolRealPrize("btc"));
} else if (coin.equalsIgnoreCase("ETH")) {
exchangeRate = Double.parseDouble(hobiDataService.getSymbolRealPrize("eth"));
} else {
// USDT、USDC 币种也支持 ERC20 类型的链,经同事确认也是比率 1:1
exchangeRate = 1.0;
}
// 充值提成比例
double rechargeCommissionRate = 0.0;
Syspara rechargeCommissionPara = sysparaService.find(SysParaCode.RECHARGE_COMMISSION_RATE.getCode());
if (rechargeCommissionPara != null) {
String rechargeCommissionRateStr = rechargeCommissionPara.getValue().trim();
if (StrUtil.isNotBlank(rechargeCommissionRateStr)) {
rechargeCommissionRate = Double.parseDouble(rechargeCommissionRateStr.trim());
}
}
RechargeBlockchain recharge = new RechargeBlockchain();
recharge.setAddress(from);
recharge.setBlockchain_name(blockchain_name);
recharge.setVolume(amount_double);
recharge.setImg(img);
recharge.setSymbol(coin.toLowerCase());
recharge.setPartyId(this.getLoginPartyId());
recharge.setSucceeded(0);
recharge.setChannel_address(channel_address);
recharge.setTx(StringUtils.isEmptyString(tx) ? "" : tx);
recharge.setAmount(Arith.roundDown(Arith.mul(amount_double, exchangeRate), 2));
recharge.setRechargeCommission(Arith.roundDown(Arith.mul(recharge.getAmount(), rechargeCommissionRate), 2));
this.rechargeBlockchainService.save(recharge, exchangeRate);
Map<String, Object> data = new HashMap<String, Object>();
resultObject.setData(data);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
/**
* 充值订单详情
* <p>
* order_no 订单号
*/
@RequestMapping(action + "get.action")
public Object get(HttpServletRequest request) throws IOException {
String order_no = request.getParameter("order_no");
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return resultObject;
}
try {
Map<String, Object> map = new HashMap<String, Object>();
RechargeBlockchain order = this.rechargeBlockchainService.findByOrderNo(order_no);
map.put("order_no", order.getOrder_no());
map.put("volume", order.getVolume());
map.put("amount", order.getAmount());
map.put("create_time", DateUtils.format(order.getCreated(), DateUtils.DF_yyyyMMddHHmmss));
map.put("from", order.getAddress());
map.put("coin", order.getSymbol().toUpperCase());
map.put("coin_blockchain",
order.getSymbol().toUpperCase().indexOf("BTC") != -1
|| order.getSymbol().toUpperCase().indexOf("ETH") != -1 ? order.getSymbol().toUpperCase()
: "USDT_" + order.getBlockchain_name().toUpperCase());
map.put("fee", 0);
map.put("state", order.getSucceeded());
map.put("tx", order.getTx());
map.put("img", order.getImg());
map.put("channel_address", order.getChannel_address());
resultObject.setData(map);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
/**
* 充值记录
*/
@RequestMapping(action + "list.action")
public Object list(HttpServletRequest request) throws IOException {
String page_no = request.getParameter("page_no");
String page_size = request.getParameter("page_size");
ResultObject resultObject = new ResultObject();
resultObject = this.readSecurityContextFromSession(resultObject);
if (!"0".equals(resultObject.getCode())) {
return resultObject;
}
try {
if (StringUtils.isNullOrEmpty(page_no)) {
page_no = "1";
}
if (StringUtils.isNullOrEmpty(page_size)) {
page_size = "10";
}
if (!StringUtils.isInteger(page_no)) {
throw new BusinessException("页码不是整数");
}
if (Integer.valueOf(page_no).intValue() <= 0) {
throw new BusinessException("页码不能小于等于0");
}
int page_no_int = Integer.valueOf(page_no).intValue();
Page pageInfo = this.walletLogService.pagedQueryRecharge(page_no_int, Integer.parseInt(page_size), this.getLoginPartyId(), "1");
List<Map<String, Object>> data = pageInfo.getElements();
for (Map<String, Object> log : data) {
if (null == log.get("coin") || !StringUtils.isNotEmpty(log.get("coin").toString())) {
log.put("coin", Constants.WALLET);
} else {
log.put("coin", log.get("coin").toString().toUpperCase());
}
logger.info("-----> rechargeBlockchain!list.action 方法中, log:" + log);
Object currentSymbol = log.get("symbol");
if (currentSymbol == null) {
log.put("coin_blockchain", "unknow");
} else {
if (currentSymbol.toString().toUpperCase().indexOf("BTC") != -1
|| currentSymbol.toString().toUpperCase().indexOf("ETH") != -1) {
log.put("coin_blockchain", currentSymbol.toString().toUpperCase());
} else {
Object chainName = log.get("blockchain_name");
if (chainName == null) {
chainName = "unknow";
}
log.put("coin_blockchain", "USDT_" + chainName.toString().toUpperCase());
}
}
log.put("fee", 0);
log.put("from", log.get("address") == null ? null : log.get("address").toString());
Object oriAmount = log.get("amount");
Object oriVolume = log.get("volume");
if (oriAmount != null) {
//Arith.round(money,2);
// 换算成 USDT 的充值金额
String strAmount = String.valueOf(oriAmount);
strAmount = (new BigDecimal(strAmount)).toPlainString();
int idx = strAmount.indexOf(".");
if (idx < 0) {
log.put("amount", strAmount + ".00");
} else {
int len = strAmount.substring(idx + 1).length();
/*if (len == 1) {
log.put("amount", strAmount + "0");
} else {
log.put("amount", strAmount.substring(0, idx + 3));
}*/
if (len <= 10) {
log.put("amount", strAmount);
} else {
log.put("amount", strAmount.substring(0, idx + 10));
}
}
}
if (oriVolume != null) {
// 原始充值币种下的金额
// 注意科学计数法问题
String strVolume = String.valueOf(oriVolume);
strVolume = (new BigDecimal(strVolume)).toPlainString();
int idx = strVolume.indexOf(".");
if (idx < 0) {
log.put("volume", strVolume + ".00");
} else {
int len = strVolume.substring(idx + 1).length();
if (len <= 10) {
log.put("volume", strVolume);
} else {
log.put("volume", strVolume.substring(0, idx + 10));
}
}
}
}
resultObject.setData(pageInfo);
} catch (BusinessException e) {
resultObject.setCode("1");
resultObject.setMsg(e.getMessage());
} catch (Throwable t) {
resultObject.setCode("1");
resultObject.setMsg("程序错误");
logger.error("error:", t);
}
return resultObject;
}
private String verif(String amount, String coin, String img, String from, String tx) {
if (StringUtils.isNullOrEmpty(amount)) {
return "充值数量必填";
}
if (!StringUtils.isDouble(amount)) {
return "充值数量输入错误,请输入浮点数";
}
if (Double.valueOf(amount).doubleValue() <= 0) {
return "充值数量不能小于等于0";
}
if (StringUtils.isEmptyString(coin)) {
return "请输入充值币种";
}
// if (1 == this.sysparaService.find("can_recharge").getInteger()) {
// // 允许在线充值
// boolean recharge_must_need_qr = this.sysparaService.find("recharge_must_need_qr").getBoolean();
// if (recharge_must_need_qr) {
// if (StringUtils.isEmptyString(img))
// return "请上传图片";
// }
// }
double recharge_limit_min = Double.valueOf(sysparaService.find("recharge_limit_min").getValue());
double recharge_limit_max = Double.valueOf(sysparaService.find("recharge_limit_max").getValue());
double amountVal = Double.valueOf(amount);
if ("usdt".equals(coin)) {
if (amountVal < recharge_limit_min) {
throw new BusinessException("充值价值不得小于最小限额");
}
if (amountVal > recharge_limit_max) {
throw new BusinessException("充值价值不得大于最大限额");
}
} else {
double fee = 1;
if (coin.equalsIgnoreCase("BTC")) {
fee = sysparaService.find("btc_exchange_usdt").getDouble();
} else if (coin.equalsIgnoreCase("ETH")) {
fee = sysparaService.find("eth_exchange_usdt").getDouble();
}
double transfer_usdt = Arith.mul(fee, amountVal);// 对应usdt价格
if (transfer_usdt < recharge_limit_min) {
throw new BusinessException("充值价值不得小于最小限额");
}
if (transfer_usdt > recharge_limit_max) {
throw new BusinessException("充值价值不得大于最大限额");
}
}
if (StringUtils.isEmptyString(from)) {
return "请输入地址";
}
// if (StringUtils.isEmptyString(tx)) {
// return "请输入转账hash";
// }
return null;
}
/**
* 获取最新价格(仅仅充值用)
*
* @return
*/
@RequestMapping(action + "fee.action")
public Object getRealtimeBySymbol(HttpServletRequest request) {
ResultObject resultObject = new ResultObject();
String symbol = request.getParameter("symbol");
JSONObject object = new JSONObject();
if (symbol == null) {
object.put("price", "0");
} else if (symbol.equalsIgnoreCase("btc")) {
object.put("price", hobiDataService.getSymbolRealPrize("btc"));
} else if (symbol.equalsIgnoreCase("eth")) {
object.put("price", hobiDataService.getSymbolRealPrize("eth"));
} else {
object.put("price", "1");
}
resultObject.setData(object);
return resultObject;
}
}