From 61759071dc7bc474b3bdbf25992e6c7271ae1cc6 Mon Sep 17 00:00:00 2001
From: Administrator <15274802129@163.com>
Date: Sun, 20 Sep 2026 15:30:37 +0800
Subject: [PATCH] feat(station): 添加手动控制面板功能

---
 src/main/java/com/xcong/excoin/modules/station/controller/StationController.java |   65 +++++++++++++++++++++++++++++++-
 1 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/src/main/java/com/xcong/excoin/modules/station/controller/StationController.java b/src/main/java/com/xcong/excoin/modules/station/controller/StationController.java
index b6c2a9b..b32b786 100644
--- a/src/main/java/com/xcong/excoin/modules/station/controller/StationController.java
+++ b/src/main/java/com/xcong/excoin/modules/station/controller/StationController.java
@@ -1,6 +1,7 @@
 package com.xcong.excoin.modules.station.controller;
 
 import com.xcong.excoin.common.response.Result;
+import com.xcong.excoin.modules.station.model.InstanceInfo;
 import com.xcong.excoin.modules.station.registry.InstanceRegistry;
 import com.xcong.excoin.modules.station.service.StationService;
 import io.swagger.annotations.Api;
@@ -9,6 +10,7 @@
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import java.util.Collection;
 
 /**
  * Station 管理接口 — 实例列表 / 启停 / 状态 / 事件查询
@@ -28,13 +30,30 @@
     @ApiOperation("获取所有在线 JAR 实例")
     @GetMapping("/list")
     public Result list() {
-        return Result.ok(instanceRegistry.list());
+        // 内存注册表只维护心跳信息,别名从 DB 合并(心跳重建实例对象时不会丢失)
+        Collection<InstanceInfo> instances = instanceRegistry.list();
+        for (InstanceInfo info : instances) {
+            info.setAliasName(stationService.getAlias(info.getApiKeyMd5()));
+        }
+        return Result.ok(instances);
     }
 
     @ApiOperation("获取单个实例状态")
     @GetMapping("/status")
     public Result status(@RequestParam String apiKeyMd5) {
-        return Result.ok(instanceRegistry.get(apiKeyMd5));
+        InstanceInfo info = instanceRegistry.get(apiKeyMd5);
+        if (info != null) {
+            info.setAliasName(stationService.getAlias(apiKeyMd5));
+        }
+        return Result.ok(info);
+    }
+
+    @ApiOperation("编辑实例别名(空白 = 清除别名)")
+    @PostMapping("/alias")
+    public Result saveAlias(@RequestParam String apiKeyMd5,
+                            @RequestParam(required = false) String alias) {
+        stationService.saveAlias(apiKeyMd5, alias);
+        return Result.ok("别名已保存");
     }
 
     @ApiOperation("启动指定 apiKeyMd5 的策略")
@@ -69,4 +88,46 @@
         stationService.updateConfig(apiKeyMd5, params);
         return Result.ok("参数已保存,请手动点击「启动」使新配置生效");
     }
+
+    @ApiOperation("取消多仓止盈止损挂单")
+    @PostMapping("/cancel-long-tp-sl")
+    public Result cancelLongTpSl(@RequestParam String apiKeyMd5) {
+        stationService.cancelLongTpSl(apiKeyMd5);
+        return Result.ok("指令已发送");
+    }
+
+    @ApiOperation("取消空仓止盈止损挂单")
+    @PostMapping("/cancel-short-tp-sl")
+    public Result cancelShortTpSl(@RequestParam String apiKeyMd5) {
+        stationService.cancelShortTpSl(apiKeyMd5);
+        return Result.ok("指令已发送");
+    }
+
+    @ApiOperation("生成多仓止盈止损挂单")
+    @PostMapping("/rebuild-long-tp-sl")
+    public Result rebuildLongTpSl(@RequestParam String apiKeyMd5) {
+        stationService.rebuildLongTpSl(apiKeyMd5);
+        return Result.ok("指令已发送");
+    }
+
+    @ApiOperation("生成空仓止盈止损挂单")
+    @PostMapping("/rebuild-short-tp-sl")
+    public Result rebuildShortTpSl(@RequestParam String apiKeyMd5) {
+        stationService.rebuildShortTpSl(apiKeyMd5);
+        return Result.ok("指令已发送");
+    }
+
+    @ApiOperation("多单平仓")
+    @PostMapping("/close-long")
+    public Result closeLong(@RequestParam String apiKeyMd5) {
+        stationService.closeLong(apiKeyMd5);
+        return Result.ok("指令已发送");
+    }
+
+    @ApiOperation("空单平仓")
+    @PostMapping("/close-short")
+    public Result closeShort(@RequestParam String apiKeyMd5) {
+        stationService.closeShort(apiKeyMd5);
+        return Result.ok("指令已发送");
+    }
 }

--
Gitblit v1.9.1