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) { return Result.fail("apiKey 错误,未找到该配置"); } 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); } }