Administrator
4 hours ago f59672ea4359c6728021824c926f456d884718cf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.xcong.excoin.modules.gateApi;
 
import com.xcong.excoin.common.response.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
 
/**
 * Gate 配置控制面板 REST 接口。
 */
@Slf4j
@RestController
@RequestMapping("/api/gate")
@Api(tags = "Gate配置管理")
public class GateConfigController {
 
    @Autowired
    private GateWebSocketClientManager clientManager;
 
    @Autowired
    private GateConfigPersistenceService persistenceService;
 
    @Autowired
    private GateLogBuffer logBuffer;
 
    /**
     * 根据 apiKey 加载配置,不存在则返回空对象让前端用默认值填充。
     */
    @PostMapping("/config/load")
    @ApiOperation("根据 apiKey 加载配置")
    public Result loadConfig(@RequestParam String apiKey) {
        if (apiKey == null || apiKey.trim().isEmpty()) {
            return Result.fail("apiKey 不能为空");
        }
        GateConfigDTO dto = persistenceService.load(apiKey);
        if (dto == null) {
            dto = new GateConfigDTO();
        }
        dto.setApiKey(apiKey);
        return Result.ok(dto);
    }
 
    /**
     * 获取当前运行中的配置。
     */
    @GetMapping("/config")
    @ApiOperation("获取当前运行策略的配置")
    public Result getConfig() {
        GateConfig config = clientManager.getConfig();
        if (config == null) {
            return Result.fail("策略未初始化");
        }
        return Result.ok(GateConfigDTO.from(config));
    }
 
    /**
     * 保存配置到文件。
     */
    @PostMapping("/config")
    @ApiOperation("保存配置")
    public Result saveConfig(@RequestBody GateConfigDTO dto) {
        if (dto.getApiKey() == null || dto.getApiKey().trim().isEmpty()) {
            return Result.fail("apiKey 不能为空");
        }
        persistenceService.save(dto.getApiKey(), dto);
        return Result.ok("配置已保存,需要重启策略才能生效");
    }
 
    /**
     * 重启网格策略:停止 → 用指定 apiKey 的配置重新初始化。
     */
    @PostMapping("/restart")
    @ApiOperation("重启策略")
    public Result restart(@RequestParam String apiKey) {
        if (apiKey == null || apiKey.trim().isEmpty()) {
            return Result.fail("apiKey 不能为空");
        }
        try {
            GateConfigDTO dto = persistenceService.load(apiKey);
            if (dto == null) {
                return Result.fail("未找到该 apiKey 的配置文件,请先保存配置");
            }
            GateConfig newConfig = persistenceService.buildFromDTO(dto, apiKey);
            clientManager.restartWithConfig(newConfig);
            logBuffer.info("策略已使用 apiKey=" + maskKey(apiKey) + " 的配置重启");
            return Result.ok("策略已使用新配置重启");
        } catch (Exception e) {
            log.error("[GateConfig] 重启策略失败", e);
            return Result.fail("重启失败: " + e.getMessage());
        }
    }
 
    /**
     * 获取策略运行状态。
     */
    @GetMapping("/status")
    @ApiOperation("获取策略状态")
    public Result getStatus() {
        GateGridTradeService service = clientManager.getGridTradeService();
        if (service == null) {
            return Result.ok("STOPPED");
        }
        return Result.ok(service.isStrategyActive() ? "ACTIVE" : "STOPPED");
    }
 
    /**
     * 停止策略。
     */
    @PostMapping("/stop")
    @ApiOperation("停止策略")
    public Result stop() {
        clientManager.stopStrategy();
        return Result.ok("策略已停止");
    }
 
    /**
     * SSE 日志流。
     */
    @GetMapping(value = "/logs", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    @ApiOperation("实时日志 SSE 流")
    public SseEmitter streamLogs() {
        return logBuffer.subscribe();
    }
 
    private static String maskKey(String key) {
        if (key == null || key.length() <= 8) return "***";
        return key.substring(0, 4) + "****" + key.substring(key.length() - 4);
    }
}