package com.zioinfo.cms.banner; import com.zioinfo.cms.banner.mapper.BannerMapper; import com.zioinfo.cms.common.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; import java.time.LocalDateTime; import java.util.List; import java.util.Map; /** * 배너/프로모션 API. 노출 스케줄(startAt~endAt) + active 기반 현재 노출 조회. */ @RestController @RequestMapping("/api/cms/banner") @RequiredArgsConstructor public class BannerController { private final BannerMapper mapper; @GetMapping public ApiResponse> list(@RequestParam(required = false) String bannerType, @RequestParam(required = false) String position) { return ApiResponse.ok(mapper.findAll(bannerType, position)); } /** 현재 노출 대상(active + 스케줄 유효). */ @GetMapping("/active") public ApiResponse> active(@RequestParam(required = false) String position) { return ApiResponse.ok(mapper.findActiveNow(position)); } @GetMapping("/{id}") public ApiResponse get(@PathVariable Long id) { CmsBanner b = mapper.findById(id); if (b == null) throw new RuntimeException("ERR-CMS-BANNER-404: 배너 없음"); return ApiResponse.ok(b); } @PostMapping public ApiResponse create(@RequestBody Map req, Authentication auth) { CmsBanner b = bind(new CmsBanner(), req); b.setCreatedBy(auth != null ? auth.getName() : "system"); mapper.insert(b); return ApiResponse.ok(mapper.findById(b.getId())); } @PutMapping("/{id}") public ApiResponse update(@PathVariable Long id, @RequestBody Map req) { CmsBanner b = mapper.findById(id); if (b == null) throw new RuntimeException("ERR-CMS-BANNER-404: 배너 없음"); bind(b, req); mapper.update(b); return ApiResponse.ok(mapper.findById(id)); } @DeleteMapping("/{id}") public ApiResponse delete(@PathVariable Long id) { mapper.delete(id); return ApiResponse.ok(null); } private CmsBanner bind(CmsBanner b, Map r) { if (r.containsKey("name")) b.setName(str(r.get("name"))); if (r.containsKey("bannerType")) b.setBannerType(str(r.get("bannerType"))); if (r.containsKey("imageUrl")) b.setImageUrl(str(r.get("imageUrl"))); if (r.containsKey("linkUrl")) b.setLinkUrl(str(r.get("linkUrl"))); if (r.containsKey("position")) b.setPosition(str(r.get("position"))); if (r.containsKey("targetRule")) b.setTargetRule(jsonStr(r.get("targetRule"))); if (r.containsKey("sortOrder")) b.setSortOrder(intOf(r.get("sortOrder"))); if (r.containsKey("active")) b.setActive(Boolean.parseBoolean(String.valueOf(r.get("active")))); if (r.containsKey("startAt")) b.setStartAt(dt(r.get("startAt"))); if (r.containsKey("endAt")) b.setEndAt(dt(r.get("endAt"))); if (b.getBannerType() == null) b.setBannerType("PROMOTION"); return b; } private String str(Object o) { return o == null ? null : String.valueOf(o); } private Integer intOf(Object o) { if (o == null) return null; try { return Integer.valueOf(String.valueOf(o).trim()); } catch (Exception e) { return null; } } private LocalDateTime dt(Object o) { if (o == null || String.valueOf(o).isBlank()) return null; try { return LocalDateTime.parse(String.valueOf(o)); } catch (Exception e) { return null; } } private String jsonStr(Object o) { if (o == null) return null; if (o instanceof String s) return s; try { return new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(o); } catch (Exception e) { return String.valueOf(o); } } }