147 lines
5.6 KiB
Java
147 lines
5.6 KiB
Java
package com.goldenchart.controller;
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import com.goldenchart.entity.GcChartSlot;
|
|
import com.goldenchart.entity.GcChartWorkspace;
|
|
import com.goldenchart.service.ChartSettingsService;
|
|
import lombok.RequiredArgsConstructor;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import org.springframework.http.ResponseEntity;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* 차트 워크스페이스 설정 REST API.
|
|
*
|
|
* GET /api/chart/workspace - 전체 설정 로드 (프론트 시작 시 호출)
|
|
* POST /api/chart/workspace - 전체 설정 저장
|
|
* PUT /api/chart/workspace/layout - 레이아웃만 변경
|
|
* PUT /api/chart/slot/{index} - 특정 슬롯 저장
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/chart")
|
|
@RequiredArgsConstructor
|
|
@Slf4j
|
|
public class ChartSettingsController {
|
|
|
|
private final ChartSettingsService settingsService;
|
|
private final ObjectMapper objectMapper;
|
|
|
|
/** 헤더에서 userId 또는 deviceId 추출 */
|
|
private Long userId(Map<String, String> headers) {
|
|
String v = headers.get("x-user-id");
|
|
return v != null ? Long.parseLong(v) : null;
|
|
}
|
|
private String deviceId(Map<String, String> headers) {
|
|
return headers.getOrDefault("x-device-id", "anonymous");
|
|
}
|
|
|
|
/**
|
|
* 프론트엔드 시작 시 전체 워크스페이스 로드.
|
|
* DB에 저장된 설정이 없으면 204 반환 → 프론트는 기본값 사용.
|
|
*/
|
|
@GetMapping("/workspace")
|
|
public ResponseEntity<?> getWorkspace(
|
|
@RequestHeader Map<String, String> headers) {
|
|
GcChartWorkspace ws = settingsService.getWorkspaceWithSlots(
|
|
userId(headers), deviceId(headers));
|
|
|
|
if (ws == null) return ResponseEntity.noContent().build();
|
|
|
|
return ResponseEntity.ok(toDto(ws));
|
|
}
|
|
|
|
/**
|
|
* 전체 워크스페이스 저장 (자동 저장 / 명시 저장).
|
|
*/
|
|
@PostMapping("/workspace")
|
|
public ResponseEntity<?> saveWorkspace(
|
|
@RequestHeader Map<String, String> headers,
|
|
@RequestBody Map<String, Object> body) {
|
|
Long uid = userId(headers);
|
|
String did = deviceId(headers);
|
|
String layoutId = (String) body.getOrDefault("layoutId", "1");
|
|
String syncJson = body.containsKey("syncOptions")
|
|
? toJson(body.get("syncOptions")) : null;
|
|
@SuppressWarnings("unchecked")
|
|
List<Map<String, Object>> slotsData = (List<Map<String, Object>>) body.get("slots");
|
|
|
|
GcChartWorkspace ws = settingsService.saveAll(uid, did, layoutId, syncJson,
|
|
slotsData != null ? slotsData : List.of());
|
|
return ResponseEntity.ok(toDto(ws));
|
|
}
|
|
|
|
/**
|
|
* 레이아웃만 변경.
|
|
*/
|
|
@PutMapping("/workspace/layout")
|
|
public ResponseEntity<?> updateLayout(
|
|
@RequestHeader Map<String, String> headers,
|
|
@RequestBody Map<String, Object> body) {
|
|
String layoutId = (String) body.get("layoutId");
|
|
String syncJson = body.containsKey("syncOptions") ? toJson(body.get("syncOptions")) : null;
|
|
GcChartWorkspace ws = settingsService.saveWorkspace(
|
|
userId(headers), deviceId(headers), layoutId, syncJson);
|
|
return ResponseEntity.ok(Map.of("layoutId", ws.getLayoutId()));
|
|
}
|
|
|
|
/**
|
|
* 특정 슬롯 설정 저장.
|
|
*/
|
|
@PutMapping("/slot/{slotIndex}")
|
|
public ResponseEntity<?> saveSlot(
|
|
@RequestHeader Map<String, String> headers,
|
|
@PathVariable int slotIndex,
|
|
@RequestBody Map<String, Object> body) {
|
|
GcChartSlot slot = settingsService.saveSlot(
|
|
userId(headers), deviceId(headers), slotIndex, body);
|
|
return ResponseEntity.ok(slotToDto(slot));
|
|
}
|
|
|
|
// ── DTO 변환 ────────────────────────────────────────────────────────────────
|
|
|
|
private Map<String, Object> toDto(GcChartWorkspace ws) {
|
|
Map<String, Object> dto = new HashMap<>();
|
|
dto.put("id", ws.getId());
|
|
dto.put("layoutId", ws.getLayoutId());
|
|
dto.put("syncOptions", parseJson(ws.getSyncOptionsJson()));
|
|
dto.put("slots", ws.getSlots().stream()
|
|
.map(this::slotToDto)
|
|
.collect(Collectors.toList()));
|
|
return dto;
|
|
}
|
|
|
|
private Map<String, Object> slotToDto(GcChartSlot s) {
|
|
Map<String, Object> dto = new HashMap<>();
|
|
dto.put("slotIndex", s.getSlotIndex());
|
|
dto.put("symbol", s.getSymbol());
|
|
dto.put("timeframe", s.getTimeframe());
|
|
dto.put("chartType", s.getChartType());
|
|
dto.put("theme", s.getTheme());
|
|
dto.put("mode", s.getMode());
|
|
dto.put("logScale", s.getLogScale());
|
|
dto.put("drawingsLocked", s.getDrawingsLocked());
|
|
dto.put("drawingsVisible", s.getDrawingsVisible());
|
|
dto.put("indicators", parseJson(s.getIndicatorsJson()));
|
|
dto.put("drawings", parseJson(s.getDrawingsJson()));
|
|
dto.put("paneLayout", parseJson(s.getPaneLayoutJson()));
|
|
dto.put("mainChartStyle", parseJson(s.getMainChartStyleJson()));
|
|
return dto;
|
|
}
|
|
|
|
private Object parseJson(String json) {
|
|
if (json == null) return null;
|
|
try { return objectMapper.readValue(json, Object.class); }
|
|
catch (Exception e) { return null; }
|
|
}
|
|
|
|
private String toJson(Object obj) {
|
|
try { return objectMapper.writeValueAsString(obj); }
|
|
catch (Exception e) { return null; }
|
|
}
|
|
}
|