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-admin/src/main/java/com/yami/trading/api/controller/trader/ApiTraderUserController.java | 139 +++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 124 insertions(+), 15 deletions(-)
diff --git a/trading-order-admin/src/main/java/com/yami/trading/api/controller/trader/ApiTraderUserController.java b/trading-order-admin/src/main/java/com/yami/trading/api/controller/trader/ApiTraderUserController.java
index 3622def..9269697 100644
--- a/trading-order-admin/src/main/java/com/yami/trading/api/controller/trader/ApiTraderUserController.java
+++ b/trading-order-admin/src/main/java/com/yami/trading/api/controller/trader/ApiTraderUserController.java
@@ -1,10 +1,12 @@
package com.yami.trading.api.controller.trader;
+import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yami.trading.bean.contract.domain.ContractOrder;
import com.yami.trading.bean.item.domain.Item;
import com.yami.trading.bean.trader.domain.Trader;
import com.yami.trading.bean.trader.domain.TraderFollowUser;
+import com.yami.trading.bean.trader.domain.TraderFollowUserOrder;
import com.yami.trading.bean.trader.domain.TraderUser;
import com.yami.trading.common.constants.Constants;
import com.yami.trading.common.exception.BusinessException;
@@ -20,7 +22,6 @@
import com.yami.trading.service.trader.TraderUserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -121,6 +122,7 @@
ResultObject resultObject = new ResultObject();
String type = request.getParameter("type");
String page_no = request.getParameter("page_no");
+ String page_size = request.getParameter("page_size");
try {
if (StringUtils.isNullOrEmpty(page_no)) {
page_no = "1";
@@ -131,7 +133,11 @@
if (Integer.valueOf(page_no).intValue() <= 0) {
throw new YamiShopBindException("页码不能小于等于0");
}
- Page<T> page = new Page<>(1, 1000000);
+ int pageSize = 10;
+ if (!StringUtils.isNullOrEmpty(page_size) && StringUtils.isInteger(page_size)) {
+ pageSize = Math.max(1, Math.min(50, Integer.parseInt(page_size)));
+ }
+ Page<?> page = new Page<>(Integer.parseInt(page_no), pageSize);
String partyId = SecurityUtils.getCurrentUserId();
@@ -152,41 +158,92 @@
}
+ /** 交易员 SYMBOLS 可能为多品种,取第一个用于展示/查 Item */
+ private static String firstTraderSymbol(String symbolsRaw) {
+ if (symbolsRaw == null || symbolsRaw.trim().isEmpty()) {
+ return "";
+ }
+ for (String part : symbolsRaw.split("[;;,,\\s]+")) {
+ if (part != null && !part.trim().isEmpty()) {
+ return part.trim();
+ }
+ }
+ return "";
+ }
+
+ /**
+ * 供前端 i18n 映射的常见跟单失败原因(存库仍为原文)。
+ */
+ private static String followFailReasonKey(String reason) {
+ if (reason == null) {
+ return null;
+ }
+ String r = reason.trim();
+ if (r.isEmpty()) {
+ return null;
+ }
+ if (r.contains("余额不足")) {
+ return "INSUFFICIENT_BALANCE";
+ }
+ if (r.contains("只能选择交易员带单币种")) {
+ return "SYMBOL_NOT_IN_TRADER_LIST";
+ }
+ if (r.contains("跟单参数输入错误")) {
+ return "INVALID_FOLLOW_PARAMS";
+ }
+ if (r.contains("Insufficient balance") || r.contains("insufficient balance")) {
+ return "INSUFFICIENT_BALANCE";
+ }
+ return null;
+ }
+
private Map<String, Object> bulidData(TraderUser entity, String type, Page page) throws ParseException {
List<Map<String, Object>> trader_order = new ArrayList<Map<String, Object>>();
- List<TraderFollowUser> follow_users = new ArrayList<TraderFollowUser>();
List<Map<String, Object>> follow_traders = new ArrayList<Map<String, Object>>();
- follow_users = traderFollowUserService.findByPartyId(entity.getPartyId());
- double folllow_trader_num = 0;
- if (follow_users != null) {
- folllow_trader_num = follow_users.size();
- }
+ long folllow_trader_num = traderFollowUserService.countByPartyId(entity.getPartyId());
+ IPage<TraderFollowUser> traderUserPage = null;
/**
- * 跟随的交易员
+ * 跟随的交易员(按更新时间倒序分页,最新在前)
*/
if ("trader".equals(type)) {
- if (follow_users != null) {
- for (TraderFollowUser user : follow_users) {
+ Page<TraderFollowUser> pg = new Page<>(page.getCurrent(), page.getSize());
+ traderUserPage = traderFollowUserService.pageByPartyId(pg, entity.getPartyId());
+ if (traderUserPage.getRecords() != null) {
+ for (TraderFollowUser user : traderUserPage.getRecords()) {
Trader trader = traderService.findByPartyId(user.getTraderPartyId());
- Item item = itemService.findBySymbol(trader.getSymbols());
+ if (trader == null) {
+ continue;
+ }
+ String primarySymbol = firstTraderSymbol(trader.getSymbols());
+ Item item = StringUtils.isEmptyString(primarySymbol) ? null : itemService.findBySymbol(primarySymbol);
Map<String, Object> follow_trader = new HashMap<String, Object>();
follow_trader.put("profit", user.getProfit());
- follow_trader.put("profitRation", BigDecimal.valueOf(user.getProfit()).divide(BigDecimal.valueOf(user.getAmountSum()), RoundingMode.HALF_UP));
+ BigDecimal profitRatio = BigDecimal.ZERO;
+ if (user.getAmountSum() > 0D) {
+ profitRatio = BigDecimal.valueOf(user.getProfit()).divide(BigDecimal.valueOf(user.getAmountSum()), 8,
+ RoundingMode.HALF_UP);
+ }
+ follow_trader.put("profitRation", profitRatio);
follow_trader.put("amountSum", user.getAmountSum());
follow_trader.put("username", trader.getName());
String path = Constants.WEB_URL + "/public/showimg!showImg.action?imagePath=" + trader.getImg();
follow_trader.put("img", path);
follow_trader.put("id", trader.getUuid());
- follow_trader.put("followState", "1");
+ follow_trader.put("followState", user.getState());
+ follow_trader.put("followFailReason", user.getFailReason());
+ String failKey = followFailReasonKey(user.getFailReason());
+ follow_trader.put("follow_fail_reason_key", failKey != null ? failKey : "");
+ follow_trader.put("followLastFailTime", user.getLastFailTime());
follow_trader.put("followType", user.getFollowType());
follow_trader.put("volume", user.getVolume());
follow_trader.put("volumeMax", user.getVolumeMax());
+ follow_trader.put("lever_rate", user.getLeverRate());
follow_trader.put("followNow", trader.getFollowerNow());
follow_trader.put("followMax", trader.getFollowerMax());
- follow_trader.put("symbols", item.getName());
+ follow_trader.put("symbols", item != null ? item.getName() : (StringUtils.isEmptyString(trader.getSymbols()) ? "" : trader.getSymbols()));
follow_traders.add(follow_trader);
}
}
@@ -202,6 +259,10 @@
map.put("orders", trader_order);
map.put("traders", follow_traders);
map.put("folllow_trader_num", folllow_trader_num);
+ map.put("traders_total", traderUserPage != null ? traderUserPage.getTotal() : folllow_trader_num);
+ if ("orders".equals(type) || "hisorders".equals(type)) {
+ map.put("orders_total", page.getTotal());
+ }
map.put("id", entity.getUuid());
@@ -219,6 +280,54 @@
}
+ /**
+ * 当前跟单持仓列表。
+ * 同时注册无 {@code !} 的路径,避免部分网关/WAF 对 {@code traderUser!positions.action} 返回 404。
+ */
+ @RequestMapping(value = { action + "positions.action", "/api/traderUser/positions" })
+ public Object positions() {
+ ResultObject resultObject = new ResultObject();
+ String partyId = SecurityUtils.getCurrentUserId();
+ try {
+ List<ContractOrder> positions = contractOrderService.selectContractOrderByUserIdAndFollowAndState(
+ partyId, ContractOrder.ORDER_FOLLOW, ContractOrder.STATE_SUBMITTED);
+ List<Map<String, Object>> data = new ArrayList<>();
+ Map<String, String> followTraderNameCache = new HashMap<>();
+ Map<String, String> followTraderUuidCache = new HashMap<>();
+ if (positions != null) {
+ for (ContractOrder position : positions) {
+ Map<String, Object> row = contractOrderService.bulidOne(position);
+ String traderName = "";
+ String traderUuid = "";
+ if (position != null && !StringUtils.isEmptyString(position.getOrderNo())) {
+ TraderFollowUserOrder link = traderFollowUserOrderService.findByPartyIdAndOrderNo(partyId,
+ position.getOrderNo());
+ if (link != null && !StringUtils.isEmptyString(link.getTraderPartyId())) {
+ String tp = link.getTraderPartyId();
+ if (!followTraderNameCache.containsKey(tp)) {
+ Trader tr = traderService.findByPartyId(tp);
+ followTraderNameCache.put(tp, tr != null && !StringUtils.isEmptyString(tr.getName()) ? tr.getName() : "");
+ followTraderUuidCache.put(tp, tr != null && !StringUtils.isEmptyString(tr.getUuid()) ? tr.getUuid() : "");
+ }
+ traderName = followTraderNameCache.getOrDefault(tp, "");
+ traderUuid = followTraderUuidCache.getOrDefault(tp, "");
+ }
+ }
+ row.put("follow_trader_name", traderName);
+ row.put("follow_trader_id", traderUuid);
+ data.add(row);
+ }
+ }
+ resultObject.setCode("0");
+ resultObject.setData(data);
+ } catch (Exception e) {
+ resultObject.setCode("1");
+ resultObject.setMsg("程序错误");
+ logger.error("error:", e);
+ }
+ return resultObject;
+ }
+
public static int daysBetween(Date smdate, Date bdate) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
smdate = sdf.parse(sdf.format(smdate));
--
Gitblit v1.9.3