|
@@ -17,6 +17,7 @@ import org.apache.commons.lang3.time.DurationFormatUtils;
|
|
|
import org.jsoup.Connection;
|
|
import org.jsoup.Connection;
|
|
|
import org.redisson.api.RLock;
|
|
import org.redisson.api.RLock;
|
|
|
import org.redisson.api.RedissonClient;
|
|
import org.redisson.api.RedissonClient;
|
|
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
@@ -123,6 +124,9 @@ public class CoinServiceImpl implements CoinService {
|
|
|
private BookmarkMapper bookmarkMapper;
|
|
private BookmarkMapper bookmarkMapper;
|
|
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
|
|
|
+ private CoinGateMapper coinGateMapper;
|
|
|
|
|
+
|
|
|
|
|
+ @Resource
|
|
|
private RedissonClient redissonClient;
|
|
private RedissonClient redissonClient;
|
|
|
|
|
|
|
|
@Resource
|
|
@Resource
|
|
@@ -1784,6 +1788,19 @@ public class CoinServiceImpl implements CoinService {
|
|
|
renderMainSearch4OrderHistoryProductType(historyOrderList);
|
|
renderMainSearch4OrderHistoryProductType(historyOrderList);
|
|
|
//result = (JSONArray) JSON.toJSON(historyOrderList);
|
|
//result = (JSONArray) JSON.toJSON(historyOrderList);
|
|
|
return historyOrderPageInfo;
|
|
return historyOrderPageInfo;
|
|
|
|
|
+ } else if (params.getString("nameEn").equals("orderHistorySpotProductType")) {
|
|
|
|
|
+ PageHelper.startPage(params.getInteger("pageNo"), params.getInteger("pageSize"), true);
|
|
|
|
|
+
|
|
|
|
|
+ List<CoinSpotOrders> spotOrdersList = new ArrayList<>();
|
|
|
|
|
+ String exchangeCategory = params.getString("exchangeCategory");
|
|
|
|
|
+ if ("6".equals(exchangeCategory)){
|
|
|
|
|
+ List<CoinGateSpotOrders> gateSpotOrdersList = coinGateMapper.findHistorySpotOrderList(params.toJavaObject(Map.class));
|
|
|
|
|
+ renderMainSearch4OrderHistorySpotProductType(gateSpotOrdersList, spotOrdersList);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ PageInfo<CoinSpotOrders> historyOrderPageInfo = new PageInfo<>(spotOrdersList);
|
|
|
|
|
+
|
|
|
|
|
+ return historyOrderPageInfo;
|
|
|
} else if (params.getString("nameEn").equals("traderList")) {
|
|
} else if (params.getString("nameEn").equals("traderList")) {
|
|
|
PageHelper.startPage(params.getInteger("pageNo"), params.getInteger("pageSize"), true);
|
|
PageHelper.startPage(params.getInteger("pageNo"), params.getInteger("pageSize"), true);
|
|
|
List<CoinTrader> mixTraderList = coinMapper.findMixTraderList(params.toJavaObject(Map.class));
|
|
List<CoinTrader> mixTraderList = coinMapper.findMixTraderList(params.toJavaObject(Map.class));
|
|
@@ -2276,6 +2293,52 @@ public class CoinServiceImpl implements CoinService {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 动态格式化数字:小数点后,从第一个非0数字开始,保留指定的有效位数
|
|
|
|
|
+ * * @param value 原始数值
|
|
|
|
|
+ * @param keepFraction 需要保留的非0有效小数位数 (如你的需求是 3)
|
|
|
|
|
+ * @return 格式化后的清爽字符串
|
|
|
|
|
+ */
|
|
|
|
|
+ public static String formatDynamicScale(BigDecimal value, int keepFraction) {
|
|
|
|
|
+ // 1. 判空防雷
|
|
|
|
|
+ if (value == null || value.compareTo(BigDecimal.ZERO) == 0) {
|
|
|
|
|
+ return "0";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 2. 取绝对值去零并转纯文本,方便字符串分析 (负数不影响我们找小数点)
|
|
|
|
|
+ String plainStr = value.abs().stripTrailingZeros().toPlainString();
|
|
|
|
|
+ int dotIndex = plainStr.indexOf('.');
|
|
|
|
|
+
|
|
|
|
|
+ // 3. 如果没有小数点(纯整数),直接返回去零后的原始字符串
|
|
|
|
|
+ if (dotIndex == -1) {
|
|
|
|
|
+ return value.stripTrailingZeros().toPlainString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 4. 计算小数点后连续的 0 的个数
|
|
|
|
|
+ int leadingZeros = 0;
|
|
|
|
|
+ String fractionPart = plainStr.substring(dotIndex + 1);
|
|
|
|
|
+ for (int i = 0; i < fractionPart.length(); i++) {
|
|
|
|
|
+ if (fractionPart.charAt(i) == '0') {
|
|
|
|
|
+ leadingZeros++;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ break; // 遇到第一个非 0 数字,停止计数
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 5. 核心逻辑:计算目标标度 (Target Scale)
|
|
|
|
|
+ // 例如:0.00000098333 -> 连续6个0,保留3位 -> 目标标度为 6 + 3 = 9
|
|
|
|
|
+ int targetScale = leadingZeros + keepFraction;
|
|
|
|
|
+
|
|
|
|
|
+ // 6. 截断保留指定精度
|
|
|
|
|
+ // 注意:这里强烈建议使用 RoundingMode.DOWN (向下取整/直接截断)
|
|
|
|
|
+ // 在金融/币圈,数量和金额通常宁愿截断,也不能四舍五入(HALF_UP),防止出现"超卖/超买"的资金盘差异
|
|
|
|
|
+ BigDecimal scaledValue = value.setScale(targetScale, RoundingMode.DOWN);
|
|
|
|
|
+
|
|
|
|
|
+ // 7. 最后做一次兜底去零。
|
|
|
|
|
+ // 防止出现例如截断后变成 139.990,去零后变成更清爽的 139.99
|
|
|
|
|
+ return scaledValue.stripTrailingZeros().toPlainString();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
private void renderMainSearch4TraderList(List<CoinTrader> mixTraderList) {
|
|
private void renderMainSearch4TraderList(List<CoinTrader> mixTraderList) {
|
|
|
for (CoinTrader mixTrader : mixTraderList) {
|
|
for (CoinTrader mixTrader : mixTraderList) {
|
|
|
mixTrader.setLastTradeTime(DateUtils.longToString(Long.valueOf(mixTrader.getLastTradeTime())));
|
|
mixTrader.setLastTradeTime(DateUtils.longToString(Long.valueOf(mixTrader.getLastTradeTime())));
|
|
@@ -2487,6 +2550,47 @@ public class CoinServiceImpl implements CoinService {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
|
+ * 渲染获取全部历史委托-现货
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param spotOrdersList
|
|
|
|
|
+ */
|
|
|
|
|
+ private void renderMainSearch4OrderHistorySpotProductType(List<CoinGateSpotOrders> gateSpotOrdersList, List<CoinSpotOrders> spotOrdersList) {
|
|
|
|
|
+ for (CoinGateSpotOrders coinGateSpotOrders : gateSpotOrdersList) {
|
|
|
|
|
+ CoinSpotOrders coinSpotOrders = new CoinSpotOrders();
|
|
|
|
|
+ BeanUtils.copyProperties(coinGateSpotOrders, coinSpotOrders);
|
|
|
|
|
+
|
|
|
|
|
+ // 币种名称
|
|
|
|
|
+ coinSpotOrders.setCurrencyPair(coinGateSpotOrders.getCurrencyPair().replace("_USDT", ""));
|
|
|
|
|
+ // 订单状态
|
|
|
|
|
+ coinSpotOrders.setStatus(InitRunner.publicParamsMap.get("gateStatus").getString(coinGateSpotOrders.getStatus()));
|
|
|
|
|
+ if ("cancelled".equals(coinGateSpotOrders.getStatus()) && coinGateSpotOrders.getFilledTotal().compareTo(BigDecimal.ZERO) > 0) {
|
|
|
|
|
+ coinSpotOrders.setStatus("已结束的订单");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 结束状态
|
|
|
|
|
+ coinSpotOrders.setFinishAs(InitRunner.publicParamsMap.get("gatefinishAs").getString(coinGateSpotOrders.getFinishAs()));
|
|
|
|
|
+ if ("cancelled".equals(coinGateSpotOrders.getFinishAs()) && coinGateSpotOrders.getFilledTotal().compareTo(BigDecimal.ZERO) > 0) {
|
|
|
|
|
+ coinSpotOrders.setFinishAs("部分成交");
|
|
|
|
|
+ }
|
|
|
|
|
+ // 交易方向
|
|
|
|
|
+ coinSpotOrders.setSide(InitRunner.publicParamsMap.get("spotSide").getString(coinGateSpotOrders.getSide()));
|
|
|
|
|
+ // 订单类型
|
|
|
|
|
+ coinSpotOrders.setType(InitRunner.publicParamsMap.get("orderType").getString(coinGateSpotOrders.getType()));
|
|
|
|
|
+ // 委托数量,委托价格,已成交数量,成交均价,成交总金额,手续费
|
|
|
|
|
+ coinSpotOrders.setAmount(formatDynamicScale(coinGateSpotOrders.getAmount(), 3));
|
|
|
|
|
+ coinSpotOrders.setPrice(formatDynamicScale(coinGateSpotOrders.getPrice(), 3));
|
|
|
|
|
+ coinSpotOrders.setFilledAmount(formatDynamicScale(coinGateSpotOrders.getFilledAmount(), 3));
|
|
|
|
|
+ coinSpotOrders.setAvgDealPrice(formatDynamicScale(coinGateSpotOrders.getAvgDealPrice(), 3));
|
|
|
|
|
+ coinSpotOrders.setFilledTotal(formatDynamicScale(coinGateSpotOrders.getFilledTotal(), 3));
|
|
|
|
|
+ coinSpotOrders.setFee(formatDynamicScale(coinGateSpotOrders.getFee(), 3));
|
|
|
|
|
+
|
|
|
|
|
+ coinSpotOrders.setCreateTimeMs(DateUtils.longToString(coinGateSpotOrders.getCreateTimeMs()));
|
|
|
|
|
+ coinSpotOrders.setUpdateTimeMs(DateUtils.longToString(coinGateSpotOrders.getUpdateTimeMs()));
|
|
|
|
|
+
|
|
|
|
|
+ spotOrdersList.add(coinSpotOrders);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
* 渲染获取全部当前委托
|
|
* 渲染获取全部当前委托
|
|
|
*
|
|
*
|
|
|
* @param result
|
|
* @param result
|