goldenChat base source add
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
package com.goldenchart.service;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.goldenchart.entity.GcChartSlot;
|
||||
import com.goldenchart.entity.GcChartWorkspace;
|
||||
import com.goldenchart.repository.GcChartWorkspaceRepository;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 차트 워크스페이스·슬롯 설정 저장/조회 서비스.
|
||||
* userId 또는 deviceId 중 하나를 식별자로 사용한다.
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
@Transactional
|
||||
public class ChartSettingsService {
|
||||
|
||||
private final GcChartWorkspaceRepository workspaceRepo;
|
||||
private final ObjectMapper objectMapper;
|
||||
|
||||
// ── 워크스페이스 조회 ──────────────────────────────────────────────────────
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public GcChartWorkspace getWorkspace(Long userId, String deviceId) {
|
||||
return findWorkspace(userId, deviceId).orElse(null);
|
||||
}
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
public GcChartWorkspace getWorkspaceWithSlots(Long userId, String deviceId) {
|
||||
if (userId != null) {
|
||||
return workspaceRepo.findWithSlotsByUserId(userId).orElse(null);
|
||||
}
|
||||
return workspaceRepo.findWithSlotsByDeviceId(deviceId).orElse(null);
|
||||
}
|
||||
|
||||
// ── 워크스페이스 저장 (생성 또는 전체 업데이트) ────────────────────────────
|
||||
|
||||
public GcChartWorkspace saveWorkspace(Long userId, String deviceId,
|
||||
String layoutId, String syncOptionsJson) {
|
||||
GcChartWorkspace ws = findWorkspace(userId, deviceId)
|
||||
.orElseGet(() -> GcChartWorkspace.builder()
|
||||
.userId(userId)
|
||||
.deviceId(deviceId)
|
||||
.layoutId(layoutId)
|
||||
.slots(new ArrayList<>())
|
||||
.build());
|
||||
ws.setLayoutId(layoutId);
|
||||
ws.setSyncOptionsJson(syncOptionsJson);
|
||||
return workspaceRepo.save(ws);
|
||||
}
|
||||
|
||||
// ── 슬롯 설정 저장 ─────────────────────────────────────────────────────────
|
||||
|
||||
public GcChartSlot saveSlot(Long userId, String deviceId, int slotIndex,
|
||||
Map<String, Object> slotData) {
|
||||
GcChartWorkspace ws = findOrCreateWorkspace(userId, deviceId);
|
||||
|
||||
GcChartSlot slot = ws.getSlots().stream()
|
||||
.filter(s -> s.getSlotIndex() == slotIndex)
|
||||
.findFirst()
|
||||
.orElseGet(() -> {
|
||||
GcChartSlot newSlot = GcChartSlot.builder()
|
||||
.workspace(ws)
|
||||
.slotIndex(slotIndex)
|
||||
.build();
|
||||
ws.getSlots().add(newSlot);
|
||||
return newSlot;
|
||||
});
|
||||
|
||||
applySlotData(slot, slotData);
|
||||
workspaceRepo.save(ws);
|
||||
return slot;
|
||||
}
|
||||
|
||||
// ── 전체 워크스페이스 + 슬롯 일괄 저장 (프론트 최초 로드 또는 전체 저장) ──
|
||||
|
||||
public GcChartWorkspace saveAll(Long userId, String deviceId,
|
||||
String layoutId, String syncOptionsJson,
|
||||
List<Map<String, Object>> slotsData) {
|
||||
GcChartWorkspace ws = findOrCreateWorkspace(userId, deviceId);
|
||||
ws.setLayoutId(layoutId);
|
||||
ws.setSyncOptionsJson(syncOptionsJson);
|
||||
|
||||
// 슬롯 동기화
|
||||
List<GcChartSlot> existing = ws.getSlots();
|
||||
for (int i = 0; i < slotsData.size(); i++) {
|
||||
final int idx = i;
|
||||
GcChartSlot slot = existing.stream()
|
||||
.filter(s -> s.getSlotIndex() == idx)
|
||||
.findFirst()
|
||||
.orElseGet(() -> {
|
||||
GcChartSlot ns = GcChartSlot.builder()
|
||||
.workspace(ws).slotIndex(idx).build();
|
||||
existing.add(ns);
|
||||
return ns;
|
||||
});
|
||||
applySlotData(slot, slotsData.get(i));
|
||||
}
|
||||
// 초과 슬롯 제거
|
||||
existing.removeIf(s -> s.getSlotIndex() >= slotsData.size());
|
||||
|
||||
return workspaceRepo.save(ws);
|
||||
}
|
||||
|
||||
// ── private helpers ────────────────────────────────────────────────────────
|
||||
|
||||
private java.util.Optional<GcChartWorkspace> findWorkspace(Long userId, String deviceId) {
|
||||
if (userId != null) return workspaceRepo.findByUserId(userId);
|
||||
return workspaceRepo.findByDeviceId(deviceId);
|
||||
}
|
||||
|
||||
private GcChartWorkspace findOrCreateWorkspace(Long userId, String deviceId) {
|
||||
return findWorkspace(userId, deviceId)
|
||||
.orElseGet(() -> workspaceRepo.save(GcChartWorkspace.builder()
|
||||
.userId(userId).deviceId(deviceId).layoutId("1").build()));
|
||||
}
|
||||
|
||||
private void applySlotData(GcChartSlot slot, Map<String, Object> d) {
|
||||
if (d.containsKey("symbol")) slot.setSymbol((String) d.get("symbol"));
|
||||
if (d.containsKey("timeframe")) slot.setTimeframe((String) d.get("timeframe"));
|
||||
if (d.containsKey("chartType")) slot.setChartType((String) d.get("chartType"));
|
||||
if (d.containsKey("theme")) slot.setTheme((String) d.get("theme"));
|
||||
if (d.containsKey("mode")) slot.setMode((String) d.get("mode"));
|
||||
if (d.containsKey("logScale")) slot.setLogScale(Boolean.parseBoolean(d.get("logScale").toString()));
|
||||
if (d.containsKey("drawingsLocked")) slot.setDrawingsLocked(Boolean.parseBoolean(d.get("drawingsLocked").toString()));
|
||||
if (d.containsKey("drawingsVisible"))slot.setDrawingsVisible(Boolean.parseBoolean(d.get("drawingsVisible").toString()));
|
||||
try {
|
||||
if (d.containsKey("indicators")) slot.setIndicatorsJson(objectMapper.writeValueAsString(d.get("indicators")));
|
||||
if (d.containsKey("drawings")) slot.setDrawingsJson(objectMapper.writeValueAsString(d.get("drawings")));
|
||||
if (d.containsKey("paneLayout")) slot.setPaneLayoutJson(objectMapper.writeValueAsString(d.get("paneLayout")));
|
||||
if (d.containsKey("mainChartStyle")) slot.setMainChartStyleJson(objectMapper.writeValueAsString(d.get("mainChartStyle")));
|
||||
} catch (JsonProcessingException e) {
|
||||
log.error("슬롯 JSON 직렬화 실패", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user