From befbf57e4112d07003bff18102f556a1e5a154de Mon Sep 17 00:00:00 2001
From: zj <1772600164@qq.com>
Date: Wed, 22 Apr 2026 10:53:37 +0800
Subject: [PATCH] 1
---
trading-order-service/src/main/java/com/yami/trading/service/trader/impl/TraderFollowUserOrderServiceImpl.java | 428 +++++++++++++++++++++++++++++++++--------------------
1 files changed, 267 insertions(+), 161 deletions(-)
diff --git a/trading-order-service/src/main/java/com/yami/trading/service/trader/impl/TraderFollowUserOrderServiceImpl.java b/trading-order-service/src/main/java/com/yami/trading/service/trader/impl/TraderFollowUserOrderServiceImpl.java
index f9f7a99..f5e66cc 100644
--- a/trading-order-service/src/main/java/com/yami/trading/service/trader/impl/TraderFollowUserOrderServiceImpl.java
+++ b/trading-order-service/src/main/java/com/yami/trading/service/trader/impl/TraderFollowUserOrderServiceImpl.java
@@ -5,23 +5,24 @@
import com.yami.trading.bean.contract.domain.ContractApplyOrder;
import com.yami.trading.bean.contract.domain.ContractOrder;
import com.yami.trading.bean.model.*;
+import com.yami.trading.bean.syspara.domain.Syspara;
import com.yami.trading.bean.trader.domain.*;
import com.yami.trading.common.constants.Constants;
import com.yami.trading.common.constants.RedisKeys;
import com.yami.trading.common.util.*;
import com.yami.trading.dao.trader.TraderFollowUserOrderMapper;
-import com.yami.trading.service.FollowMoneyLogService;
-import com.yami.trading.service.FollowWalletService;
import com.yami.trading.service.MoneyLogService;
import com.yami.trading.service.WalletService;
import com.yami.trading.service.contract.ContractApplyOrderService;
import com.yami.trading.service.contract.ContractOrderService;
import com.yami.trading.service.syspara.SysparaService;
+import com.yami.trading.bean.trader.FollowCommissionType;
import com.yami.trading.service.trader.*;
import com.yami.trading.service.user.UserRecomService;
import com.yami.trading.service.user.UserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@@ -29,9 +30,17 @@
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
@Service
public class TraderFollowUserOrderServiceImpl implements TraderFollowUserOrderService {
+ private static final ExecutorService FOLLOW_EXECUTOR = Executors.newFixedThreadPool(8);
+
+ private final ConcurrentMap<String, Boolean> followTaskKeys = new ConcurrentHashMap<>();
+
@Resource
private TraderService traderService;
@Resource
@@ -42,13 +51,7 @@
private WalletService walletService;
@Resource
- private FollowWalletService followWalletService;
-
- @Resource
private MoneyLogService moneyLogService;
-
- @Resource
- private FollowMoneyLogService followMoneyLogService;
@Resource
private TraderOrderService traderOrderService;
@@ -62,7 +65,14 @@
@Resource
private UserService userService;
-
+
+ @Resource
+ private FollowCommissionService followCommissionService;
+
+ @Lazy
+ @Resource
+ private ContractOrderService contractOrderService;
+
private static Log logger = LogFactory.getLog(TraderFollowUserOrderServiceImpl.class);
public List<Map<String, Object>> getPaged(Page page, String partyId, String state) {
@@ -86,6 +96,12 @@
// parameters.put("partyId", partyId);
//
// queryString.append(" order by trader_user_order.CREATE_TIME desc ");
+ Long total = traderFollowUserOrderMapper.countListDatas(partyId, state);
+ if (total != null) {
+ page.setTotal(total.longValue());
+ } else {
+ page.setTotal(0L);
+ }
List<Map<String, Object>> datas = traderFollowUserOrderMapper.listDatas((page.getCurrent() - 1) * page.getSize(), page.getSize(), partyId, state);
List<Map<String, Object>> data = this.bulidData(datas);
@@ -146,8 +162,10 @@
map.put("force_close_price", entity.get("force_close_price"));
String trader_party_id = (String) entity.get("trader_party_id");
- User user = userService.findByUserId(trader_party_id);
- map.put("trader_username", user.getUserName());
+ User user = trader_party_id == null ? null : userService.findByUserId(trader_party_id);
+ map.put("trader_username", user != null && user.getUserName() != null ? user.getUserName() : "");
+ Object fn = entity.get("follow_trader_name");
+ map.put("follow_trader_name", fn != null ? fn.toString() : "");
result_traders.add(map);
}
@@ -190,20 +208,63 @@
}
@Override
+ public void syncFollowUserOrderLinkAfterContractClose(ContractOrder contractOrder) {
+ if (contractOrder == null || !ContractOrder.STATE_CREATED.equals(contractOrder.getState())) {
+ return;
+ }
+ String partyId = contractOrder.getPartyId();
+ String orderNo = contractOrder.getOrderNo();
+ if (StringUtils.isEmptyString(partyId) || StringUtils.isEmptyString(orderNo)) {
+ return;
+ }
+ TraderFollowUserOrder link = findByPartyIdAndOrderNo(partyId, orderNo);
+ if (link == null) {
+ return;
+ }
+ if (!TraderFollowUserOrder.STATE_SUBMITTED.equals(link.getState())
+ && !TraderFollowUserOrder.STATE_PROCESSING_CLOSE.equals(link.getState())) {
+ return;
+ }
+ link.setState(ContractOrder.STATE_CREATED);
+ update(link);
+ }
+
+ @Override
+ public void reconcileStaleSubmittedMappings(String partyId, String traderPartyId) {
+ if (StringUtils.isEmptyString(partyId) || StringUtils.isEmptyString(traderPartyId)) {
+ return;
+ }
+ List<TraderFollowUserOrder> list = traderFollowUserOrderMapper.selectList(
+ Wrappers.<TraderFollowUserOrder>lambdaQuery()
+ .eq(TraderFollowUserOrder::getPartyId, partyId)
+ .eq(TraderFollowUserOrder::getTraderPartyId, traderPartyId)
+ .eq(TraderFollowUserOrder::getState, TraderFollowUserOrder.STATE_SUBMITTED));
+ if (list == null || list.isEmpty()) {
+ return;
+ }
+ for (TraderFollowUserOrder link : list) {
+ if (StringUtils.isEmptyString(link.getUserOrderNo())) {
+ continue;
+ }
+ ContractOrder co = contractOrderService.findByOrderNo(link.getUserOrderNo());
+ if (co != null && ContractOrder.STATE_CREATED.equals(co.getState())) {
+ link.setState(ContractOrder.STATE_CREATED);
+ update(link);
+ }
+ }
+ }
+
+ @Override
public void traderOpen(ContractOrder contractOrder, ContractApplyOrderService contractApplyOrderService, ContractOrderService contractOrderService, int follow) {
if (isOrNotTrader(contractOrder.getPartyId())) {
- CreateDelayThread lockDelayThread = new CreateDelayThread(contractOrder, contractApplyOrderService, contractOrderService, follow);
- Thread t = new Thread(lockDelayThread);
- t.start();
+ FOLLOW_EXECUTOR.submit(new CreateDelayThread(contractOrder, contractApplyOrderService, contractOrderService, follow));
}
}
@Override
public void traderClose(ContractOrder contractOrder, ContractOrderService contractOrderService) {
if (isOrNotTrader(contractOrder.getPartyId())) {
- CloseDelayThread lockDelayThread = new CloseDelayThread(contractOrder, contractOrderService);
- Thread t = new Thread(lockDelayThread);
- t.start();
+ FOLLOW_EXECUTOR.submit(new CloseDelayThread(contractOrder, contractOrderService));
}
// else {
@@ -228,7 +289,7 @@
public void run() {
try {
- List<TraderFollowUser> users = traderFollowUserService.findByTrader_partyId(contractOrder.getPartyId()); //查找当前交易员的跟随者
+ List<TraderFollowUser> users = traderFollowUserService.findActiveByTraderPartyId(contractOrder.getPartyId()); // 查找当前交易员的有效跟随者
if (users != null) {
for (TraderFollowUser user : users) {
if (!"".equals(user.getPartyId())) {
@@ -236,8 +297,16 @@
* 判断当前用户最多还可以买几张
*/
try {
+ String taskKey = buildTaskKey(contractOrder.getOrderNo(), user.getPartyId(), ContractApplyOrder.OFFSET_OPEN);
+ if (followTaskKeys.putIfAbsent(taskKey, Boolean.TRUE) != null) {
+ continue;
+ }
+ if (hasOpenFollowMapping(user.getPartyId(), contractOrder.getOrderNo())) {
+ followTaskKeys.remove(taskKey);
+ continue;
+ }
List<TraderFollowUserOrder> userOrders = findByPartyIdAndTraderPartyIdAndState(user.getPartyId(), contractOrder.getPartyId(), ContractOrder.STATE_SUBMITTED);
- double volume_last = user.getVolumeMax(); // 跟单时设置的最大持仓张数
+ double volume_last = user.getVolumeMax(); // 跟单时设置的最大持仓币数量
if (userOrders != null) {
for (TraderFollowUserOrder userOrder : userOrders) {
volume_last = Arith.sub(volume_last, userOrder.getVolume());
@@ -247,6 +316,10 @@
continue;
}
+ if (user.getSymbol() != null && !user.getSymbol().trim().isEmpty()
+ && !user.getSymbol().trim().equalsIgnoreCase(contractOrder.getSymbol())) {
+ continue;
+ }
ContractApplyOrder order = new ContractApplyOrder();
order.setOrderNo(DateUtil.getToday("yyMMddHHmmss") + RandomUtil.getRandomNum(8));
order.setPartyId(user.getPartyId());
@@ -255,28 +328,12 @@
order.setOffset(ContractApplyOrder.OFFSET_OPEN);
order.setFollow(follow); // 标记为跟单订单
- /**
- * 跟单固定张数/固定比例---选择 1,固定张数,2,固定比例
- */
- if ("1".equals(user.getFollowType())) {
- if (volume_last < user.getVolume()) { // 剩余可下单张数小于用户设置的固定开仓单数
- order.setVolume(new BigDecimal(volume_last));
- order.setVolumeOpen(new BigDecimal(volume_last));
- } else {
- order.setVolume(BigDecimal.valueOf(user.getVolume()));
- order.setVolumeOpen(BigDecimal.valueOf(user.getVolume()));
- }
- }
- if ("2".equals(user.getFollowType())) {
- if (volume_last < Arith.mul(contractOrder.getVolumeOpen().doubleValue(), user.getVolume())) {
- order.setVolume(new BigDecimal(volume_last));
- order.setVolumeOpen(new BigDecimal(volume_last));
- } else {
- order.setVolume(BigDecimal.valueOf(Arith.mul(contractOrder.getVolumeOpen().doubleValue(), user.getVolume())));
- order.setVolumeOpen(BigDecimal.valueOf(Arith.mul(contractOrder.getVolumeOpen().doubleValue(), user.getVolume())));
- }
- }
- order.setLeverRate(contractOrder.getLeverRate()); // 杠杆
+ double targetVolume = Math.min(volume_last, user.getVolume());
+ order.setVolume(BigDecimal.valueOf(targetVolume));
+ order.setVolumeOpen(BigDecimal.valueOf(targetVolume));
+ // 跟随者 LEVER_RATE:仅当 >0 时采用;未设置/null(库空→0)/≤0 一律默认 1 倍,不回退交易员持仓杠杆
+ double configuredLever = user.getLeverRate() > 0D ? user.getLeverRate() : 1D;
+ order.setLeverRate(BigDecimal.valueOf(configuredLever));
order.setPrice(contractOrder.getTradeAvgPrice()); // 永续合约交易委托价格,设置为交易员成交无效
order.setStopPriceProfit(contractOrder.getStopPriceProfit());
order.setStopPriceLoss(contractOrder.getStopPriceLoss());
@@ -331,6 +388,14 @@
traderFollowUserService.update(user);
} catch (Exception e) {
logger.error("TraderFollowUserOrderServiceImpl_error:", e);
+ String msg = e.getMessage();
+ if (msg == null || msg.isEmpty()) {
+ msg = e.getClass().getSimpleName();
+ }
+ traderFollowUserService.markFollowOpenFailed(user.getPartyId(), contractOrder.getPartyId(), msg);
+ } finally {
+ String taskKey = buildTaskKey(contractOrder.getOrderNo(), user.getPartyId(), ContractApplyOrder.OFFSET_OPEN);
+ followTaskKeys.remove(taskKey);
}
}
ThreadUtils.sleep(10);
@@ -379,12 +444,19 @@
if (orders != null) {
for (TraderFollowUserOrder order : orders) {
try {
+ String taskKey = buildTaskKey(contractOrder.getOrderNo(), order.getPartyId(), ContractApplyOrder.OFFSET_CLOSE);
+ if (followTaskKeys.putIfAbsent(taskKey, Boolean.TRUE) != null) {
+ continue;
+ }
if (ContractOrder.STATE_SUBMITTED.equals(order.getState())) {
+ order.setState(TraderFollowUserOrder.STATE_PROCESSING_CLOSE);
+ traderFollowUserOrderMapper.updateById(order);
ContractOrder user_contract_order = contractOrderService
.saveClose(order.getPartyId(), order.getUserOrderNo());
- order.setState(ContractOrder.STATE_CREATED);
- traderFollowUserOrderMapper.updateById(order);
-// ApplicationUtil.executeUpdate(order);
+ if (user_contract_order == null) {
+ order.setState(TraderFollowUserOrder.STATE_SUBMITTED);
+ traderFollowUserOrderMapper.updateById(order);
+ }
if (user_contract_order != null) {
closeUserContractOrder(user_contract_order);
@@ -394,6 +466,8 @@
} catch (Exception e) {
logger.error("error:", e);
} finally {
+ String taskKey = buildTaskKey(contractOrder.getOrderNo(), order.getPartyId(), ContractApplyOrder.OFFSET_CLOSE);
+ followTaskKeys.remove(taskKey);
}
ThreadUtils.sleep(10);
}
@@ -426,7 +500,7 @@
trader_order.setCloseTime(new Date(contractOrder.getCloseTime()));
trader_order.setCreateTime(contractOrder.getCreateTime());
trader_order.setDirection(contractOrder.getDirection());
- trader_order.setLeverRate(contractOrder.getLeverRate().doubleValue());
+ trader_order.setLeverRate(contractOrder.getLeverRate() == null ? 1D : contractOrder.getLeverRate().doubleValue());
trader_order.setState(contractOrder.getState());
trader_order.setVolumeOpen(contractOrder.getVolumeOpen().doubleValue());
@@ -461,70 +535,84 @@
*/
double follow_order_profit = 0;
- if (traderFollowUserOrder != null && contractOrder.getProfit().doubleValue() > 0) {
- Trader trader = traderService.findByPartyId(traderFollowUserOrder.getTraderPartyId());
- follow_order_profit = Arith.mul(contractOrder.getProfit().doubleValue(), trader.getProfitShareRatio());
+ if (traderFollowUserOrder != null) {
+ traderFollowUserOrder.setState(contractOrder.getState());
+ update(traderFollowUserOrder);
- FollowWallet wallet = followWalletService.saveWalletByPartyId(contractOrder.getPartyId());
- double wallet_before = wallet.getMoney().doubleValue();
- followWalletService.update(contractOrder.getPartyId(), Arith.sub(0, follow_order_profit));
+ TraderUser traderUser = traderUserService.saveTraderUserByPartyId(contractOrder.getPartyId());
+ traderUser.setProfit(Arith.add(traderUser.getProfit(), contractOrder.getProfit().doubleValue()));
+ traderUserService.update(traderUser);
- FollowMoneyLog moneylog = new FollowMoneyLog();
- moneylog.setCategory(Constants.MONEYLOG_CATEGORY_CONTRACT);
- moneylog.setAmount_before(new BigDecimal(wallet_before));
- moneylog.setAmount(BigDecimal.valueOf(Arith.sub(0, follow_order_profit)));
- moneylog.setAmount_after(BigDecimal.valueOf(Arith.sub(wallet.getMoney().doubleValue(), follow_order_profit)));
- moneylog.setLog("交易员订单号[" + traderFollowUserOrder.getTraderOrderNo() + "],跟单用户订单号["
- + contractOrder.getOrderNo() + "],跟单手续费[" + Arith.sub(0, follow_order_profit) + "]");
- moneylog.setUserId(contractOrder.getPartyId());
- moneylog.setWalletType(Constants.WALLET);
- moneylog.setContent_type(Constants.MONEYLOG_CONTENT_FOLLOW_UP_FEE);
-
- followMoneyLogService.save(moneylog);
-
- Wallet wallet_trader = walletService.saveWalletByPartyId(trader.getPartyId());
- double wallet_trader_before = wallet_trader.getMoney().doubleValue();
- walletService.update(wallet_trader.getUserId(), follow_order_profit);
-
- MoneyLog moneylog_trader = new MoneyLog();
- moneylog_trader.setCategory(Constants.MONEYLOG_CATEGORY_CONTRACT);
- moneylog_trader.setAmount_before(new BigDecimal(wallet_trader_before));
- moneylog_trader.setAmount(new BigDecimal(follow_order_profit));
- moneylog_trader.setAmount_after(BigDecimal.valueOf(Arith.add(wallet_trader.getMoney().doubleValue(), follow_order_profit)));
- moneylog_trader.setLog("交易员订单号[" + traderFollowUserOrder.getTraderOrderNo() + "],跟单用户订单号["
- + contractOrder.getOrderNo() + "],带单手续费收益[" + follow_order_profit + "]");
- moneylog_trader.setUserId(wallet_trader.getUserId());
- moneylog_trader.setWalletType(Constants.WALLET);
- moneylog_trader.setContent_type(Constants.MONEYLOG_CONTENT_FOLLOW_UP_FEE);
-
- moneyLogService.save(moneylog_trader);
-
- /**
- * 检查是否是跟单订单,如果是需要将TraderFollowUserOrder里的订单状态修改
- */
-
- if (traderFollowUserOrder != null) {
- traderFollowUserOrder.setState(contractOrder.getState());
- update(traderFollowUserOrder);
-
- /**
- * 将收益加入用户跟随累计
- */
- TraderUser traderUser = traderUserService.saveTraderUserByPartyId(contractOrder.getPartyId());
- traderUser.setProfit(Arith.add(traderUser.getProfit(), contractOrder.getProfit().doubleValue()));
- traderUserService.update(traderUser);
-
- TraderFollowUser traderFollowUser = traderFollowUserService.findByPartyIdAndTrader_partyId(
- traderFollowUserOrder.getPartyId(),
- traderFollowUserOrder.getTraderPartyId());
- /**
- * 给用户跟随表添加累计金额
- */
+ TraderFollowUser traderFollowUser = traderFollowUserService.findByPartyIdAndTrader_partyId(
+ traderFollowUserOrder.getPartyId(),
+ traderFollowUserOrder.getTraderPartyId());
+ if (traderFollowUser != null) {
traderFollowUser.setProfit(Arith.add(traderFollowUser.getProfit(), contractOrder.getProfit().doubleValue()));
traderFollowUserService.update(traderFollowUser);
-
}
- saveProfitBounsHandle(contractOrder);
+ }
+
+ if (traderFollowUserOrder != null) {
+ Trader trader = traderService.findByPartyId(traderFollowUserOrder.getTraderPartyId());
+ String commissionType = FollowCommissionType.normalizeOrLegacy(trader.getFollowCommissionType());
+ long closeSec = contractOrder.getCloseTime() != null && contractOrder.getCloseTime() > 0
+ ? contractOrder.getCloseTime()
+ : System.currentTimeMillis() / 1000L;
+ if (FollowCommissionType.isDailyProfitPct(commissionType)) {
+ followCommissionService.accumulateDailyRealizedPnl(contractOrder.getPartyId().toString(),
+ traderFollowUserOrder.getTraderPartyId(), contractOrder.getProfit(), closeSec);
+ } else if (FollowCommissionType.isLegacy(commissionType) && contractOrder.getProfit().doubleValue() > 0) {
+ follow_order_profit = Arith.mul(contractOrder.getProfit().doubleValue(), trader.getProfitShareRatio());
+
+ Wallet wallet = walletService.saveWalletByPartyId(contractOrder.getPartyId());
+ double wallet_before = wallet.getMoney().doubleValue();
+ walletService.update(contractOrder.getPartyId(), Arith.sub(0, follow_order_profit));
+
+ String sym = contractOrder.getSymbol() == null ? "" : contractOrder.getSymbol().trim();
+ if (sym.isEmpty()) {
+ sym = "-";
+ }
+ String traderName = StringUtils.isEmptyString(trader.getName()) ? trader.getPartyId() : trader.getName().trim();
+ double sharePct = Arith.mul(trader.getProfitShareRatio(), 100D);
+ String feeStr = BigDecimal.valueOf(follow_order_profit).stripTrailingZeros().toPlainString();
+ String followerLog = String.format(
+ "[跟单佣金-盈利分润(经典模式)]交易对:%s|跟单用户平仓盈利分成|分润比例:%.4f%%|交易员委托单:%s|跟单持仓单:%s|主钱包扣款:USDT %s|带单员:%s",
+ sym, sharePct, traderFollowUserOrder.getTraderOrderNo(), contractOrder.getOrderNo(), feeStr, traderName);
+ String traderLog = String.format(
+ "[跟单佣金-盈利分润(经典模式)]交易对:%s|带单员分润入账|来源跟单用户平仓盈利|分润比例:%.4f%%|跟单持仓单:%s|对应交易员委托:%s|主钱包入账:USDT %s",
+ sym, sharePct, contractOrder.getOrderNo(), traderFollowUserOrder.getTraderOrderNo(), feeStr);
+
+ MoneyLog moneylog = new MoneyLog();
+ moneylog.setCategory(Constants.MONEYLOG_CATEGORY_CONTRACT);
+ moneylog.setAmountBefore(new BigDecimal(wallet_before));
+ moneylog.setAmount(BigDecimal.valueOf(Arith.sub(0, follow_order_profit)));
+ moneylog.setAmountAfter(BigDecimal.valueOf(Arith.sub(wallet.getMoney().doubleValue(), follow_order_profit)));
+ moneylog.setLog(followerLog + "|账变:跟随者主钱包扣款");
+ moneylog.setUserId(contractOrder.getPartyId());
+ moneylog.setWalletType(Constants.WALLET);
+ moneylog.setSymbol(Constants.WALLET_USDT);
+ moneylog.setContentType(Constants.MONEYLOG_CONTENT_FOLLOW_UP_FEE);
+
+ moneyLogService.save(moneylog);
+
+ Wallet wallet_trader = walletService.saveWalletByPartyId(trader.getPartyId());
+ double wallet_trader_before = wallet_trader.getMoney().doubleValue();
+ walletService.update(wallet_trader.getUserId(), follow_order_profit);
+
+ MoneyLog moneylog_trader = new MoneyLog();
+ moneylog_trader.setCategory(Constants.MONEYLOG_CATEGORY_CONTRACT);
+ moneylog_trader.setAmountBefore(new BigDecimal(wallet_trader_before));
+ moneylog_trader.setAmount(new BigDecimal(follow_order_profit));
+ moneylog_trader.setAmountAfter(BigDecimal.valueOf(Arith.add(wallet_trader.getMoney().doubleValue(), follow_order_profit)));
+ moneylog_trader.setLog(traderLog + "|账变:带单员主钱包入账");
+ moneylog_trader.setUserId(wallet_trader.getUserId());
+ moneylog_trader.setWalletType(Constants.WALLET);
+ moneylog_trader.setSymbol(Constants.WALLET_USDT);
+ moneylog_trader.setContentType(Constants.MONEYLOG_CONTENT_FOLLOW_UP_FEE);
+
+ moneyLogService.save(moneylog_trader);
+ saveProfitBounsHandle(contractOrder);
+ }
}
}
@@ -540,6 +628,7 @@
return null;
}
+ @Override
public List<TraderFollowUserOrder> findByPartyIdAndTraderPartyIdAndState(String partyId, String trader_partyId,
String state) {
// StringBuffer queryString = new StringBuffer(
@@ -568,73 +657,89 @@
return null;
}
+ private boolean hasOpenFollowMapping(String partyId, String traderOrderNo) {
+ List<TraderFollowUserOrder> list = traderFollowUserOrderMapper.selectList(
+ Wrappers.<TraderFollowUserOrder>lambdaQuery()
+ .eq(TraderFollowUserOrder::getPartyId, partyId)
+ .eq(TraderFollowUserOrder::getTraderOrderNo, traderOrderNo)
+ .in(TraderFollowUserOrder::getState,
+ TraderFollowUserOrder.STATE_SUBMITTED,
+ TraderFollowUserOrder.STATE_PROCESSING_CLOSE));
+ return list != null && !list.isEmpty();
+ }
+
+ private String buildTaskKey(String traderOrderNo, String followerPartyId, String actionType) {
+ return traderOrderNo + ":" + followerPartyId + ":" + actionType;
+ }
+
/**
* 跟单产生手续费,奖励给推荐人
*
* @param entity
*/
public void saveFeeBounsHandle(ContractApplyOrder entity) {
- List<UserRecom> recom_parents = userRecomService.getParents(entity.getPartyId());
- if (recom_parents == null) {
- return;
- }
- if (recom_parents.isEmpty()) {
- return;
- }
- /**
- * 上级为空则直接结束
- */
-
- if ("".equals(recom_parents.get(0).getRecomUserId()) || recom_parents.get(0).getRecomUserId() == null) {
- return;
- }
-
- /**
- * 获取数据库奖金分成比例
- */
-// String trade_follow_bonus_parameters = sysparaService.find("trade_follow_bonus_parameters").getValue();
- String trade_follow_bonus_parameters = sysparaService.find("trade_follow_bonus_parameters").getSvalue();
- String[] trade_follow_bonus_array = trade_follow_bonus_parameters.split(",");
-
- /**
- * 判断有几个父级代理,最多不超过3个有奖励
- */
- for (int i = 0; i < recom_parents.size(); i++) {
- if (i >= 3) {
+ try {
+ List<UserRecom> recom_parents = userRecomService.getParents(entity.getPartyId());
+ if (recom_parents == null) {
return;
}
- /**
- * 邀请人是正式用户和演示用户才加奖金
- */
- User party = new User();
- party = userService.cacheUserBy(recom_parents.get(i).getRecomUserId());
- if (!"MEMBER".equals(party.getRoleName()) && !"GUEST".equals(party.getRoleName())) {
- continue;
+ if (recom_parents.isEmpty()) {
+ return;
}
- double pip_amount = Double.parseDouble(trade_follow_bonus_array[i]);
- double get_money = Arith.mul(entity.getFee().doubleValue(), pip_amount);
+ if ("".equals(recom_parents.get(0).getRecomUserId()) || recom_parents.get(0).getRecomUserId() == null) {
+ return;
+ }
- Wallet wallet = walletService.saveWalletByPartyId(recom_parents.get(i).getRecomUserId());
- double amount_before = wallet.getMoney().doubleValue();
-// wallet.setMoney(Arith.add(wallet.getMoney(), get_money));
- walletService.update(wallet.getUserId(), get_money);
+ Syspara bonusPara = sysparaService.find("trade_follow_bonus_parameters");
+ if (bonusPara == null || StringUtils.isEmptyString(bonusPara.getSvalue())) {
+ logger.warn("saveFeeBounsHandle: syspara trade_follow_bonus_parameters missing or empty, skip");
+ return;
+ }
+ String trade_follow_bonus_parameters = bonusPara.getSvalue().trim();
+ String[] trade_follow_bonus_array = trade_follow_bonus_parameters.split(",");
+ if (trade_follow_bonus_array.length == 0) {
+ return;
+ }
- /**
- * 保存资金日志
- */
- MoneyLog moneyLog = new MoneyLog();
- moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_REWARD);
- moneyLog.setAmount_before(new BigDecimal(amount_before));
- moneyLog.setAmount(new BigDecimal(get_money));
- moneyLog.setAmount_after(BigDecimal.valueOf(Arith.add(wallet.getMoney().doubleValue(), get_money)));
- moneyLog.setLog("第" + (i + 1) + "代用户跟单产生了交易,手续费奖励[" + get_money + "]");
- moneyLog.setUserId(recom_parents.get(i).getRecomUserId());
- moneyLog.setWalletType(Constants.WALLET);
- moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_REWARD);
- moneyLogService.save(moneyLog);
+ for (int i = 0; i < recom_parents.size(); i++) {
+ if (i >= 3) {
+ return;
+ }
+ if (i >= trade_follow_bonus_array.length) {
+ logger.warn("saveFeeBounsHandle: bonus ratio array shorter than parent index " + i + ", skip rest");
+ return;
+ }
+ User party = userService.cacheUserBy(recom_parents.get(i).getRecomUserId());
+ if (party == null || (!"MEMBER".equals(party.getRoleName()) && !"GUEST".equals(party.getRoleName()))) {
+ continue;
+ }
+ String ratioStr = trade_follow_bonus_array[i] == null ? "" : trade_follow_bonus_array[i].trim();
+ if (ratioStr.isEmpty()) {
+ continue;
+ }
+ double pip_amount = Double.parseDouble(ratioStr);
+ double get_money = Arith.mul(entity.getFee().doubleValue(), pip_amount);
+ Wallet wallet = walletService.saveWalletByPartyId(recom_parents.get(i).getRecomUserId());
+ double amount_before = wallet.getMoney().doubleValue();
+ walletService.update(wallet.getUserId(), get_money);
+
+ MoneyLog moneyLog = new MoneyLog();
+ moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_REWARD);
+ moneyLog.setAmountBefore(new BigDecimal(amount_before));
+ moneyLog.setAmount(new BigDecimal(get_money));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(wallet.getMoney().doubleValue(), get_money)));
+ moneyLog.setLog("第" + (i + 1) + "代用户跟单产生了交易,手续费奖励[" + get_money + "]");
+ moneyLog.setUserId(recom_parents.get(i).getRecomUserId());
+ moneyLog.setWalletType(Constants.WALLET);
+ moneyLog.setSymbol(Constants.WALLET_USDT);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_REWARD);
+ moneyLogService.save(moneyLog);
+ }
+ } catch (Exception e) {
+ logger.error("saveFeeBounsHandle failed (ignored so follow open is not rolled into markFollowOpenFailed), orderNo="
+ + (entity != null ? entity.getOrderNo() : "null"), e);
}
-
}
/**
@@ -693,13 +798,14 @@
*/
MoneyLog moneyLog = new MoneyLog();
moneyLog.setCategory(Constants.MONEYLOG_CATEGORY_REWARD);
- moneyLog.setAmount_before(new BigDecimal(amount_before));
+ moneyLog.setAmountBefore(new BigDecimal(amount_before));
moneyLog.setAmount(new BigDecimal(get_money));
- moneyLog.setAmount_after(BigDecimal.valueOf(Arith.add(wallet.getMoney().doubleValue(), get_money)));
+ moneyLog.setAmountAfter(BigDecimal.valueOf(Arith.add(wallet.getMoney().doubleValue(), get_money)));
moneyLog.setLog("第" + (i + 1) + "代用户跟单产生了交易,分红奖励[" + get_money + "]");
moneyLog.setUserId(recom_parents.get(i).getRecomUserId());
moneyLog.setWalletType(Constants.WALLET);
- moneyLog.setContent_type(Constants.MONEYLOG_CONTENT_REWARD);
+ moneyLog.setSymbol(Constants.WALLET_USDT);
+ moneyLog.setContentType(Constants.MONEYLOG_CONTENT_REWARD);
moneyLogService.save(moneyLog);
}
--
Gitblit v1.9.3