Files
Django/jituan/services/recharge_page_copy.py
XingQue 4b5130c824 feat: 会员/履约金页文案按俱乐部可配置
新增 club_recharge_page_copy 表与小程序/后台读写接口,kefu 菜单挂「充值页文案」。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-24 00:04:23 +08:00

205 lines
6.3 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""会员/履约金充值页文案按俱乐部读写。"""
import json
from jituan.models import ClubRechargePageCopy
from jituan.services.club_context import resolve_club_id_from_request, resolve_effective_club_id
PAGE_HUIYUAN = 'huiyuan'
PAGE_YAJIN = 'yajin'
PAGE_KEYS = {PAGE_HUIYUAN, PAGE_YAJIN}
REGIONS_BY_PAGE = {
PAGE_HUIYUAN: ('rules', 'benefits', 'advantages'),
PAGE_YAJIN: ('rules', 'benefits'),
}
REGION_SORT = {
'rules': 10,
'benefits': 20,
'advantages': 30,
}
def normalize_page_key(page_key):
key = (page_key or '').strip().lower()
return key if key in PAGE_KEYS else ''
def normalize_region_key(page_key, region_key):
key = (region_key or '').strip().lower()
allowed = REGIONS_BY_PAGE.get(page_key) or ()
return key if key in allowed else ''
def _as_items_list(raw):
if raw is None:
return []
if isinstance(raw, str):
try:
raw = json.loads(raw)
except (TypeError, ValueError):
return []
if not isinstance(raw, list):
return []
out = []
for item in raw:
if isinstance(item, dict):
out.append(item)
elif isinstance(item, str) and item.strip():
out.append({'text': item.strip()})
return out
def _normalize_items_for_region(region_key, items):
"""按区域清洗条目字段,去掉空条目。"""
cleaned = []
for item in _as_items_list(items):
if region_key == 'rules':
text = (item.get('text') or '').strip()
if text:
cleaned.append({'text': text})
elif region_key == 'benefits':
# 会员权益title/desc履约金权益label
title = (item.get('title') or '').strip()
label = (item.get('label') or '').strip()
desc = (item.get('desc') or '').strip()
icon_url = (item.get('icon_url') or '').strip()
accent = (item.get('accent_color') or '').strip()
row = {}
if title:
row['title'] = title
if label:
row['label'] = label
if desc:
row['desc'] = desc
if icon_url:
row['icon_url'] = icon_url
if accent:
row['accent_color'] = accent
if row.get('title') or row.get('label') or row.get('desc'):
cleaned.append(row)
elif region_key == 'advantages':
title = (item.get('title') or '').strip()
desc = (item.get('desc') or '').strip()
icon_url = (item.get('icon_url') or '').strip()
if not (title or desc):
continue
row = {}
if title:
row['title'] = title
if desc:
row['desc'] = desc
if icon_url:
row['icon_url'] = icon_url
cleaned.append(row)
return cleaned
def _row_to_region_payload(row, for_admin=False):
items = _as_items_list(row.items_json)
payload = {
'title': (row.title or '').strip(),
'items': items,
'enabled': bool(row.enabled),
'sort_order': int(row.sort_order or 0),
}
if for_admin:
payload['region_key'] = row.region_key
payload['page_key'] = row.page_key
return payload
def get_public_regions(club_id, page_key):
"""小程序只读:仅返回 enabled 且 items 非空的区域。"""
page_key = normalize_page_key(page_key)
if not page_key or not club_id:
return {}
rows = (
ClubRechargePageCopy.query
.filter(club_id=club_id, page_key=page_key, enabled=True)
.order_by('sort_order', 'id')
)
regions = {}
for row in rows:
items = _as_items_list(row.items_json)
if not items:
continue
regions[row.region_key] = {
'title': (row.title or '').strip(),
'items': items,
}
return regions
def get_admin_regions(club_id, page_key):
"""后台:返回该页全部区域(含未启用/空),缺省区域补空壳。"""
page_key = normalize_page_key(page_key)
if not page_key or not club_id:
return {}
allowed = REGIONS_BY_PAGE[page_key]
existing = {
row.region_key: row
for row in ClubRechargePageCopy.query.filter(club_id=club_id, page_key=page_key)
}
regions = {}
for rk in allowed:
row = existing.get(rk)
if row:
regions[rk] = _row_to_region_payload(row, for_admin=True)
else:
regions[rk] = {
'region_key': rk,
'page_key': page_key,
'title': '',
'items': [],
'enabled': False,
'sort_order': REGION_SORT.get(rk, 0),
}
return regions
def save_region(club_id, page_key, region_key, *, title='', items=None, enabled=True, sort_order=None):
page_key = normalize_page_key(page_key)
region_key = normalize_region_key(page_key, region_key)
if not club_id or not page_key or not region_key:
return None, 'page_key 或 region_key 无效'
items_clean = _normalize_items_for_region(region_key, items)
title = (title or '').strip()[:64]
enabled = bool(enabled)
if sort_order is None:
sort_order = REGION_SORT.get(region_key, 0)
try:
sort_order = int(sort_order)
except (TypeError, ValueError):
sort_order = REGION_SORT.get(region_key, 0)
row = ClubRechargePageCopy.query.filter(
club_id=club_id, page_key=page_key, region_key=region_key,
).first()
if row:
row.title = title
row.items_json = items_clean
row.enabled = enabled
row.sort_order = sort_order
row.save(update_fields=['title', 'items_json', 'enabled', 'sort_order', 'UpdateTime'])
else:
row = ClubRechargePageCopy.query.create(
club_id=club_id,
page_key=page_key,
region_key=region_key,
title=title,
items_json=items_clean,
enabled=enabled,
sort_order=sort_order,
)
return _row_to_region_payload(row, for_admin=True), None
def club_id_for_mini(request):
return resolve_club_id_from_request(request)
def club_id_for_admin(request, user):
return resolve_effective_club_id(request, user)