feat(cafe24): 진열중·판매중 기본 체크 + 분리 상품 모바일 동시 반영 선택
1) 필터 기본값 진열중·판매중을 기본 체크로 바꿨다. 체크박스는 해제 상태면 아무 값도 보내지 않아 기본값이 체크면 "사용자가 일부러 해제함"을 구분할 수 없다. 그래서 폼에 표식(f=1)을 넣어, 표식이 없으면 첫 방문(기본값), 있으면 실제 체크 상태를 따르게 했다. 표식은 목록 링크·적용 후 리다이렉트에도 이어 붙어 해제 상태가 유지된다. 2) 분리 상품의 모바일 반영 "소스를 수정하면 PC와 모바일이 같이 수정되는 것 아닌가" 라는 지적대로, PC/모바일 분리 사용 상품은 지금까지 PC 만 바뀌고 있었다(미분리 상품은 원래 함께 반영). 편집기에 「모바일도 함께」 체크박스를 추가했다. 현재 두 내용이 같으면 기본 체크라 그대로 적용하면 함께 반영되고, 내용이 다르면 기본 해제하고 경고를 띄운다 — 일부러 다르게 만든 모바일 페이지를 조용히 덮어쓰는 것이 더 큰 사고이기 때문이다. 미분리 상품은 종전처럼 항상 함께 반영하며 체크박스를 보여주지 않는다. 검증: 유닛테스트 51개 통과. 필터 판정을 5가지 경우로 확인(첫 방문·둘 다 체크·하나만· 둘 다 해제·검색 링크) — 둘 다 해제가 f=1 표식으로 유지됨. 편집기 렌더를 3가지 상태로 확인(분리+동일=기본체크, 분리+상이=기본해제+경고, 미분리=체크박스 없음). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -81,15 +81,31 @@ def _row_for_list(raw: dict[str, Any]) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
# 필터 폼이 제출됐음을 알리는 표식.
|
||||
# 체크박스는 해제 상태면 아무 값도 보내지 않으므로, 이것 없이는 "첫 방문"과
|
||||
# "사용자가 일부러 해제함"을 구분할 수 없다(기본값이 체크라서 해제가 무시된다).
|
||||
_FILTER_MARK = "f"
|
||||
|
||||
|
||||
def _filter_flags(request: Request) -> tuple[bool, bool]:
|
||||
"""(진열중만, 판매중만). 첫 방문이면 둘 다 기본 체크로 본다."""
|
||||
if request.query_params.get(_FILTER_MARK) is None:
|
||||
return True, True
|
||||
return _checked(request, "display"), _checked(request, "selling")
|
||||
|
||||
|
||||
def _list_query(request: Request, *, selected: int | None = None) -> str:
|
||||
"""현재 검색·필터를 유지한 목록 URL 쿼리스트링."""
|
||||
params: list[tuple[str, str]] = []
|
||||
keyword = (request.query_params.get("q") or "").strip()
|
||||
if keyword:
|
||||
params.append(("q", keyword))
|
||||
for flag in ("display", "selling"):
|
||||
if _checked(request, flag):
|
||||
params.append((flag, "1"))
|
||||
if request.query_params.get(_FILTER_MARK) is not None:
|
||||
# 해제 상태까지 그대로 이어지도록 표식을 함께 남긴다.
|
||||
params.append((_FILTER_MARK, "1"))
|
||||
for flag in ("display", "selling"):
|
||||
if _checked(request, flag):
|
||||
params.append((flag, "1"))
|
||||
if selected:
|
||||
params.append(("selected", str(selected)))
|
||||
return urlencode(params)
|
||||
@@ -144,8 +160,7 @@ def product_list(request: Request) -> HTMLResponse:
|
||||
st, user = checked
|
||||
|
||||
keyword = (request.query_params.get("q") or "").strip()
|
||||
only_display = _checked(request, "display")
|
||||
only_selling = _checked(request, "selling")
|
||||
only_display, only_selling = _filter_flags(request)
|
||||
|
||||
api = build_cafe24_api(st)
|
||||
rows: list[dict[str, Any]] = []
|
||||
@@ -226,6 +241,7 @@ def product_apply(
|
||||
base_fingerprint: str = Form(""),
|
||||
memo: str = Form(""),
|
||||
list_query: str = Form(""),
|
||||
apply_mobile: str = Form(""),
|
||||
):
|
||||
"""편집한 HTML 을 카페24에 즉시 적용한다.
|
||||
|
||||
@@ -285,9 +301,13 @@ def product_apply(
|
||||
status_code=303,
|
||||
)
|
||||
|
||||
# 미분리 상품은 모바일도 함께 맞춘다(PC 만 바꾸면 모바일이 어긋난다).
|
||||
# 분리 상품은 모바일을 건드리지 않는다(화면에 별도 반영 안내를 띄운다).
|
||||
mobile_html = None if current.separated_mobile else submitted
|
||||
# 미분리 상품은 모바일도 함께 맞춘다 — PC 만 바꾸면 모바일 상세가 어긋난다.
|
||||
# 분리 상품은 화면의 「모바일도 함께」 체크에 따른다(두 내용이 같으면 기본 체크,
|
||||
# 다르면 기본 해제 — 일부러 다르게 만든 모바일 페이지를 덮어쓰지 않기 위해).
|
||||
if current.separated_mobile:
|
||||
mobile_html = submitted if apply_mobile else None
|
||||
else:
|
||||
mobile_html = submitted
|
||||
|
||||
if submitted == current.description and (
|
||||
mobile_html is None or mobile_html == current.mobile_description
|
||||
|
||||
Reference in New Issue
Block a user