광고연구소

상품 목록 조회

OnSureLab

광고 상품 목록을 조회합니다. 지하철 상품(type=1)의 경우 역별 도면, 옵션, 가격 데이터가 포함됩니다.

GET

상품 목록 조회

엔드포인트
GET /api/product/ad/list
파라미터
파라미터타입필수설명
langstring-언어 코드 (기본: ko)
productTypestring-타입 필터 (콤마 구분, 예: 1,2,4)
0 또는 미입력 시 전체 조회
stationsstring-역 필터 (콤마 구분 stationId, 예: 41,42,180)
해당 역에 연결된 상품만 반환 (product_station 기반)
limitnumber-조회 개수 제한
최대 1000개
응답 필드
필드타입설명
idnumber상품 고유 ID
namestring상품명
typenumber상품 타입 (1=지하철, 2=전광판, 4=단일지하철 등)
image / imageSmallstring대표 이미지 / 썸네일 URL
pricesPrice[]상품 기본 가격 목록
locationLocation | null위치 정보 (좌표, 주소)
stationsStation[]연결된 역 목록 (product_station 기반, 모든 오프라인 상품)
saleRatenumber할인율 (%)
stations 필드 상세 (모든 오프라인 상품)
필드타입설명
idnumber역 ID
namestring역 이름 (lang에 따라 번역)
linesstring[]노선 목록 (예: ["2호선", "공항철도"])
costAdjustmentnumber역별 가격 보정값 (원)
blueprintImagestring | null역 도면 이미지 URL (다국어 지원)
optionsOption[]역 내 광고 옵션 목록 (A1, A2, B1 등)
pricesPrice[]역별 기본 가격 (기간별)

options 필드

필드타입설명
idnumber옵션 ID
namestring옵션 이름 (예: "A1", "B1")
codestring옵션 코드
position{ left, top }도면 이미지 위 표시 위치
displaySizestring디스플레이 사이즈 (예: "1920x1080")
designSizestring디자인 입고 사이즈 (예: "1920x1080")
priceAdjustmentnumber옵션별 가격 보정값 (원)

가격 계산 방식

최종가격 = stations[].prices[].price (역 기본가)
         + stations[].costAdjustment (역별 보정)
         + stations[].options[].priceAdjustment (옵션별 보정)
응답 예시
[
  // ── 지하철 상품 (type=1) ──
  {
    "id": 20,
    "name": "홍대입구역 조명광고",
    "type": 1,
    "image": "https://kr.cafe24obs.com/data/product/20/main.webp",
    "imageSmall": "https://kr.cafe24obs.com/data/product/small/20/main.webp",
    "prices": [
      { "duration": "7d", "price": 200000, "currency": "KRW" }
    ],
    "location": {
      "address": "서울특별시 마포구 양화로 지하 160",
      "lat": "37.5571",
      "lng": "126.9239"
    },
    "stations": [
      {
        "id": 239,
        "name": "홍대입구역",
        "lines": ["2호선", "공항철도", "경의중앙선"],
        "address": "서울특별시 마포구 양화로 지하 160",
        "lat": "37.5571",
        "lng": "126.9239",
        "costAdjustment": 10000,
        "blueprintImage": "https://kr.cafe24obs.com/data/.../blueprint.webp",
        "options": [
          {
            "id": 45,
            "name": "A1",
            "code": "A1",
            "position": { "left": 120, "top": 80 },
            "displaySize": "1920x1080",
            "designSize": "1920x1080",
            "priceAdjustment": 10000
          }
        ],
        "prices": [
          { "duration": "7d", "price": 200000, "currency": "KRW" },
          { "duration": "14d", "price": 380000, "currency": "KRW" }
        ]
      }
    ],
    "saleRate": 10
  },

  // ── 일반 상품 (type=2 전광판 등) ──
  // product_station에 연결된 역이 있으면 stations에 포함
  {
    "id": 458,
    "name": "강남역 전광판",
    "type": 2,
    "image": "https://kr.cafe24obs.com/data/product/458/main.webp",
    "imageSmall": "https://kr.cafe24obs.com/data/product/small/458/main.webp",
    "prices": [
      { "duration": "7d", "price": 350000, "currency": "KRW" },
      { "duration": "14d", "price": 650000, "currency": "KRW" }
    ],
    "location": {
      "address": "서울특별시 강남구 강남대로 396",
      "lat": "37.4979",
      "lng": "127.0276"
    },
    "stations": [
      {
        "id": 25,
        "name": "강남",
        "lines": ["2호선"],
        "address": "서울특별시 강남구 강남대로 지하 396",
        "lat": "37.4979",
        "lng": "127.0276",
        "costAdjustment": 0,
        "blueprintImage": null
      }
    ],
    "saleRate": 0
  }
]

필터 구조

상품 유형 필터 (productType)
UI 라벨types 배열
전체1, 2, 3, 4, 5, 7, 8
지하철1, 4
전광판2
버스정류장3, 5
현수막7
온라인8
역 필터와 상품 유형의 관계

productType stations는 독립된 두 축이지만, API 내부 동작에 의해 단방향 의존이 존재합니다.

1. 상품 유형에서 지하철(1,4)을 빼면 → 역 선택 자동 초기화

2. 역을 선택해도 → 상품 유형은 변경되지 않음

API 내부 동작

-- stations 필터가 있을 때의 쿼리 구조
FROM product p
WHERE p.isOpen = 1
  AND p.type IN (1,2,3,4,5,7,8)
  AND EXISTS (
    SELECT 1 FROM product_station ps_filter
    WHERE ps_filter.productId = p.id
      AND ps_filter.stationId IN (41, 42)  -- 합정, 홍대입구
      AND ps_filter.isOpen = 1
  )

-- EXISTS 서브쿼리로 필터링:
-- → product_station에 해당 역 레코드가 있는 상품만 결과에 포함
-- → product_station 연결이 없는 상품은 제외
--
-- stations 응답: 모든 type에서 product_station 연결이 있으면
-- stations[] 배열에 역 정보가 포함됩니다.
-- (type=1 전용 제한 제거됨)
역 선택 시 실제 결과

예시: "전체" + "합정역" 선택

요청: productType=1,2,3,4,5,7,8 & stations=합정역ID

결과: product_station에 합정역이 연결된 상품만 반환
 → type=1(지하철), type=4(단일지하철) — 거의 전부 연결
 → type=2(전광판) — 대부분 연결 (82개 중 79개)
 → type=3,5(버스정류장) — 대부분 연결
 → type=7(현수막) — 대부분 연결 (36개 중 34개)
 → type=8(온라인) — 연결 없음, 제외

참고: product_station은 지하철 전용 테이블이 아닙니다. 전광판, 현수막, 버스정류장 등 대부분의 오프라인 상품이 역에 연결되어 있어, 역 필터 시 해당 타입 상품도 함께 반환됩니다. 연결이 없는 상품(온라인 등)만 제외됩니다.

type별 stations 데이터 동작

타입목록 API stations역 상세 진입 후비고
type=1 (지하철)
포함
옵션/가격 보강여러 역에 걸친 상품, stations에 옵션(A1,B1...) + 역별 가격 포함
type=4 (단일 지하철)
포함
별도 API로 상세 조회특정 역 전용 상품, stations에 역 정보 포함
type=2 (전광판)
포함
해당 없음product_station 연결 기반, 최근접 역 매핑
type=3,5 (버스정류장)
포함
해당 없음product_station 연결 기반, 최근접 역 매핑
type=7 (현수막)
포함
해당 없음product_station 연결 기반, 최근접 역 매핑
type=8 (온라인)
빈 배열
해당 없음물리적 위치 없음, 역 필터 시 제외
type=4 역 상세 조회:type=4 상품의 역/옵션/가격 데이터는 목록 API가 아닌 별도 API로 조회합니다.
GET /api/product/subway/price   → 역별 가격
GET /api/product/subway/option  → 도면 + 옵션 (A1, A2...)

// 두 API 모두 type=1, type=4를 동일하게 처리