Files
Django/jituan/services/display_config.py

246 lines
8.8 KiB
Python
Raw 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.
"""轮播 / 公告 / 弹窗按俱乐部读取与写入。"""
from jituan.constants import CLUB_ID_DEFAULT, DATA_SCOPE_ALL
from jituan.services.club_context import (
filter_queryset_by_club,
resolve_club_id_from_request,
resolve_club_scope,
resolve_effective_club_id,
)
from rest_framework.response import Response
# 定稿 B 方案 page_key
LUNBO_PAGE_ORDER_POOL = 'order_pool'
LUNBO_PAGE_ACCEPT_ORDER = 'accept_order'
LUNBO_PAGE_MERCHANT_HOME = 'merchant_home'
LUNBO_PAGE_DASHOU_CENTER = 'dashou_center'
LUNBO_PAGE_OPTIONS = [
(LUNBO_PAGE_ORDER_POOL, '抢单池'),
(LUNBO_PAGE_ACCEPT_ORDER, '点单页'),
(LUNBO_PAGE_MERCHANT_HOME, '商家首页'),
(LUNBO_PAGE_DASHOU_CENTER, '打手个人中心背景'),
]
# 无商家/打手/管事/组长身份时,仅允许点单相关 page_key
PUBLIC_LUNBO_PAGE_KEYS = frozenset({
LUNBO_PAGE_ACCEPT_ORDER,
LUNBO_PAGE_ORDER_POOL,
})
def normalize_page_key(page_key, image_type=1):
key = (page_key or '').strip()
if image_type == 2:
return LUNBO_PAGE_DASHOU_CENTER
if key in {LUNBO_PAGE_ORDER_POOL, LUNBO_PAGE_ACCEPT_ORDER, LUNBO_PAGE_MERCHANT_HOME}:
return key
return LUNBO_PAGE_ORDER_POOL
def _user_role_profile_flags(user):
"""根据扩展表判断用户是否具备对应身份(比 UserType 更准)。"""
if not user or not getattr(user, 'is_authenticated', False):
return frozenset()
found = set()
for attr, name in (
('ShopProfile', 'shop'),
('DashouProfile', 'dashou'),
('GuanshiProfile', 'guanshi'),
('ZuzhangProfile', 'zuzhang'),
):
try:
getattr(user, attr)
found.add(name)
except Exception:
pass
return frozenset(found)
def allowed_lunbo_page_keys_for_user(user):
"""当前用户可访问的轮播/公告 page_key。"""
allowed = set(PUBLIC_LUNBO_PAGE_KEYS)
roles = _user_role_profile_flags(user)
if 'shop' in roles:
allowed.add(LUNBO_PAGE_MERCHANT_HOME)
if 'dashou' in roles:
allowed.add(LUNBO_PAGE_DASHOU_CENTER)
# 管事/组长与点单页共用 order_pool、accept_order已在 PUBLIC 中
return frozenset(allowed)
def resolve_lunbo_page_key_for_request(request, page_key=None, image_type=1):
"""
按身份限制 page_key与小程序 display-config.js 对齐):
- order_pool / accept_order任何人含未登录均可访问
- merchant_home / dashou_center未登录时按前端传入的 page_key 返回(接口 AllowAny、前端不传 JWT
- 已登录时:无对应扩展表身份则拒绝该 page_key返回 None
"""
requested = normalize_page_key(page_key, image_type=image_type)
if requested in PUBLIC_LUNBO_PAGE_KEYS:
return requested
user = getattr(request, 'user', None)
if not user or not getattr(user, 'is_authenticated', False):
return requested
allowed = allowed_lunbo_page_keys_for_user(user)
if requested in allowed:
return requested
return None
def forbid_display_write_in_all_scope(request):
if resolve_club_scope(request) == DATA_SCOPE_ALL:
return Response({'code': 403, 'msg': '请在子公司视图下修改展示配置'})
return None
def filter_popup_page_by_request(qs, request):
return filter_queryset_by_club(qs, request, club_field='club_id')
def forbid_popup_page_out_of_scope(request, page):
if resolve_club_scope(request) == DATA_SCOPE_ALL:
return None
club_id = resolve_club_id_from_request(request)
page_club = getattr(page, 'club_id', None) or CLUB_ID_DEFAULT
if page_club != club_id:
return Response({'code': 403, 'msg': '该弹窗配置不属于当前俱乐部'})
return None
def _display_club_id(request):
user = getattr(request, 'user', None)
if user is not None and getattr(user, 'is_authenticated', False):
return resolve_effective_club_id(request, user)
return resolve_effective_club_id(request, None)
def get_gonggao_content(request, notice_type=1, page_key=None):
from config.models import Gonggao
club_id = _display_club_id(request)
pk = normalize_page_key(page_key, image_type=1) if page_key else LUNBO_PAGE_ORDER_POOL
obj = Gonggao.query.filter(club_id=club_id, page_key=pk).first()
# 仅旧接口未传 page_key 时,才回退 NoticeType兼容历史单条公告
if not obj and notice_type and not page_key:
obj = Gonggao.query.filter(club_id=club_id, NoticeType=notice_type).first()
return obj.Content if obj and obj.Content else ''
def get_lunbo_urls(request, page_key=None, image_type=1):
from config.models import Lunbo
club_id = _display_club_id(request)
pk = normalize_page_key(page_key, image_type=image_type)
qs = Lunbo.query.filter(club_id=club_id, ImageType=image_type, page_key=pk)
return [row.ImageURL for row in qs.order_by('id') if row.ImageURL]
def list_response_meta(request):
from jituan.services.club_user_access import list_response_meta as _meta
return _meta(request)
def get_tupianpeizhi_url(request, image_type):
"""按俱乐部读图片配置(各俱乐部独立,不回退 xq避免串台"""
from config.models import Tupianpeizhi
club_id = _display_club_id(request)
row = Tupianpeizhi.query.filter(club_id=club_id, ImageType=image_type).first()
return (row.ImageURL or '').strip() if row else ''
TUPIAN_TYPE_LABELS = {
1: '打手规则图',
2: '默认头像',
3: '关注快手',
}
def list_tupianpeizhi_by_type(club_id, image_type):
from config.models import Tupianpeizhi
rows = Tupianpeizhi.query.filter(club_id=club_id, ImageType=image_type).order_by('id')
return [
{'id': r.id, 'image_url': r.ImageURL or '', 'access_count': r.AccessCount or 0}
for r in rows if r.ImageURL
]
def upsert_tupianpeizhi_single(club_id, image_type, image_url):
"""ImageType 1/2 每俱乐部仅一条。"""
from config.models import Tupianpeizhi
row = Tupianpeizhi.query.filter(club_id=club_id, ImageType=image_type).first()
if row:
row.ImageURL = image_url
row.save(update_fields=['ImageURL', 'UpdateTime'])
else:
Tupianpeizhi.query.create(
club_id=club_id, ImageType=image_type, ImageURL=image_url, AccessCount=0,
)
def copy_display_config(template_club_id, new_club_id):
"""从模板俱乐部复制轮播/公告/弹窗/图片配置到新俱乐部。"""
from config.models import Gonggao, Lunbo, PopupConfig, PopupImage, PopupPage, Tupianpeizhi
for row in Lunbo.query.filter(club_id=template_club_id):
Lunbo.query.create(
club_id=new_club_id,
page_key=row.page_key or 'order_pool',
ImageURL=row.ImageURL,
ImageType=row.ImageType,
)
for row in Gonggao.query.filter(club_id=template_club_id):
Gonggao.query.create(
club_id=new_club_id,
page_key=getattr(row, 'page_key', None) or 'order_pool',
NoticeType=row.NoticeType,
Content=row.Content,
)
for row in Tupianpeizhi.query.filter(club_id=template_club_id):
if Tupianpeizhi.query.filter(club_id=new_club_id, ImageType=row.ImageType).exists():
continue
Tupianpeizhi.query.create(
club_id=new_club_id,
ImageURL=row.ImageURL,
ImageType=row.ImageType,
AccessCount=0,
)
for page in PopupPage.query.filter(club_id=template_club_id).prefetch_related('popups__images'):
new_page = PopupPage.query.create(
club_id=new_club_id,
page_key=page.page_key,
name=page.name,
description=page.description,
is_active=page.is_active,
ignore_user_mute=page.ignore_user_mute,
)
for popup in page.popups.all():
new_popup = PopupConfig.query.create(
page=new_page,
popup_id=popup.popup_id,
title=popup.title,
description=popup.description,
strategy_type=popup.strategy_type,
max_count=popup.max_count,
reset_interval=popup.reset_interval,
duration=popup.duration,
force_even_muted=popup.force_even_muted,
sort_order=popup.sort_order,
is_active=popup.is_active,
start_time=popup.start_time,
end_time=popup.end_time,
)
for img in popup.images.all():
PopupImage.query.create(
popup_config=new_popup,
image_url=img.image_url,
text=img.text,
sort_order=img.sort_order,
)
from jituan.services.miniapp_assets import copy_miniapp_assets
copy_miniapp_assets(template_club_id, new_club_id)