新增 fighter_complaint_record,与我的处罚分开;点单邀请文案改为邀请点单,推荐人默认改用 icon-sub。 Co-authored-by: Cursor <cursoragent@cursor.com>
309 lines
15 KiB
Python
309 lines
15 KiB
Python
"""小程序频道与可配置图标(按俱乐部)。"""
|
||
from jituan.services.display_config import _display_club_id
|
||
|
||
ICON_FOLDER = 'beijing/tubiao/chengxutubiao'
|
||
|
||
# icon_key -> 后台展示名(文件名固定为 {icon_key}.png)
|
||
MINIAPP_ICON_META = [
|
||
('merchant_gold_banner', '商家金牌横幅(抢单/订单列表顶部)'),
|
||
# 商家首页大图(与「我的」页小图标分开配置)
|
||
('merchant_home_regular', '商家首页-常规派单大图'),
|
||
('merchant_home_custom', '商家首页-自定义派单大图'),
|
||
('merchant_home_link', '商家首页-链接派单大图'),
|
||
('merchant_home_kefu_key', '商家首页-客服密钥'),
|
||
('merchant_home_kefu_list', '商家首页-客服列表'),
|
||
('merchant_home_notice', '商家首页-公告图标'),
|
||
('merchant_home_stat_bg', '商家首页-统计卡背景'),
|
||
# 商家「我的」页功能小图标
|
||
('merchant_regular_dispatch', '我的页-常规派单'),
|
||
('merchant_custom_dispatch', '我的页-自定义派单'),
|
||
('merchant_pending_settle', '我的页-待清算'),
|
||
('merchant_kefu_key', '我的页-客服密钥'),
|
||
('merchant_kefu_list', '我的页-客服列表'),
|
||
('merchant_link_dispatch', '我的页-链接派单'),
|
||
('merchant_punish', '我的页-处罚记录'),
|
||
('merchant_rank', '我的页-商家排行'),
|
||
('merchant_refresh', '我的页-刷新'),
|
||
('fighter_recharge_member', '打手中心-会员充值横幅(左侧)'),
|
||
('fighter_recharge_deposit', '打手中心-保证金充值横幅(右侧)'),
|
||
('fighter_recharge_vip_bg', '打手会员充值页-顶部背景图'),
|
||
('fighter_deposit_bg', '打手保证金页-顶部背景图'),
|
||
('fighter_deposit_hero', '打手保证金页-卡片右侧装饰图'),
|
||
('fighter_deposit_benefit_1', '保证金页-权益图标1'),
|
||
('fighter_deposit_benefit_2', '保证金页-权益图标2'),
|
||
('fighter_deposit_benefit_3', '保证金页-权益图标3'),
|
||
('fighter_deposit_benefit_4', '保证金页-权益图标4'),
|
||
('fighter_recharge_benefit_1', '会员充值页-权益图标1'),
|
||
('fighter_recharge_benefit_2', '会员充值页-权益图标2'),
|
||
('fighter_recharge_benefit_3', '会员充值页-权益图标3'),
|
||
('fighter_recharge_advantage_1', '会员充值页-平台优势1'),
|
||
('fighter_recharge_advantage_2', '会员充值页-平台优势2'),
|
||
('fighter_recharge_advantage_3', '会员充值页-平台优势3'),
|
||
('fighter_recharge_advantage_4', '会员充值页-平台优势4'),
|
||
('fighter_order_pending', '打手中心-订单-待完成'),
|
||
('fighter_order_settling', '打手中心-订单-待结算'),
|
||
('fighter_order_done', '打手中心-订单-已完成'),
|
||
('fighter_order_closed', '打手中心-订单-已关闭'),
|
||
('fighter_trade_commission', '打手中心-佣金记录'),
|
||
('fighter_trade_withdraw', '打手中心-提现记录'),
|
||
('fighter_trade_settle', '打手中心-结算记录'),
|
||
('fighter_trade_deduct', '打手中心-扣款记录'),
|
||
('fighter_trade_recharge', '打手中心-充值记录'),
|
||
('fighter_invite_subordinate', '打手中心-我的下级'),
|
||
('fighter_invite_poster', '打手中心-推广海报'),
|
||
('fighter_invite_code', '打手中心-邀请码'),
|
||
('fighter_kuaishou_cash', '打手中心-快手提现'),
|
||
('fighter_follow_kuaishou', '打手中心-关注快手'),
|
||
('fighter_mine_copy', '打手中心-复制ID'),
|
||
('fighter_mine_edit', '打手中心-编辑资料'),
|
||
('fighter_mine_qiepian', '打手中心-切片活动横幅'),
|
||
('fighter_mine_penalty_tip', '打手中心-罚单提示图标'),
|
||
('fighter_mine_kefu', '打手中心-在线客服'),
|
||
('fighter_mine_shangjia', '打手中心-商家认证'),
|
||
('fighter_complaint_record', '打手中心-投诉记录'),
|
||
('fighter_mine_punish', '打手中心-我的处罚'),
|
||
('fighter_mine_medal', '打手中心-考核金牌'),
|
||
('fighter_mine_book', '打手中心-接单考试/规则'),
|
||
('fighter_mine_rank', '打手中心-总排行榜'),
|
||
('fighter_mine_invite', '打手中心-联系邀请人'),
|
||
('fighter_mine_contact', '打手中心-联系组长'),
|
||
('fighter_mine_record', '打手中心-会员/分红记录'),
|
||
('fighter_mine_kaohe_dafen', '打手中心-考核打分'),
|
||
('fighter_mine_kaohe_jilu', '打手中心-考核记录'),
|
||
('fighter_mine_kaohe_zhongxin', '打手中心-考核中心'),
|
||
('fighter_mine_dashou_auth', '打手中心-接单员认证'),
|
||
('fighter_mine_clear', '打手中心-清除缓存'),
|
||
('fighter_mine_switch', '打手中心-返回点单端'),
|
||
('mine_pindao', '频道入口'),
|
||
('icon_refresh', '通用刷新'),
|
||
# 点单端「我的」服务入口(客服 / 邀请须分开可配)
|
||
('cuser_mine_kefu', '点单端我的-在线客服'),
|
||
('cuser_mine_invite', '点单端我的-邀请点单'),
|
||
('cuser_mine_invitees', '点单端我的-我推荐的人'),
|
||
('guanshi_poster_bg', '管事推广海报背景'),
|
||
('zuzhang_poster_bg', '组长推广海报背景'),
|
||
('cuser_poster_bg', '点单端推荐官海报背景'),
|
||
]
|
||
|
||
MINIAPP_ICON_KEYS = [k for k, _ in MINIAPP_ICON_META]
|
||
MINIAPP_ICON_LABELS = dict(MINIAPP_ICON_META)
|
||
|
||
# 无 DB 记录时的默认相对路径(与种子脚本一致)
|
||
MINIAPP_ICON_DEFAULTS = {
|
||
key: f'{ICON_FOLDER}/{key}.png' for key in MINIAPP_ICON_KEYS
|
||
}
|
||
# 部分历史资源扩展名不同
|
||
MINIAPP_ICON_DEFAULTS['icon_refresh'] = 'beijing/guanshiduan/icon-refresh.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_refresh'] = 'beijing/guanshiduan/icon-refresh.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_gold_banner'] = 'beijing/tubiao/chengxutubiao/merchant_gold_banner.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_regular'] = 'beijing/shangjiaduan/home/regular_dispatch.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_custom'] = 'beijing/shangjiaduan/home/custom_dispatch.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_link'] = 'beijing/shangjiaduan/home/link_dispatch.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_kefu_key'] = 'beijing/shangjiaduan/home/kefu_key.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_kefu_list'] = 'beijing/shangjiaduan/home/kefu_list.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_notice'] = 'beijing/shangjiaduan/home/notice.png'
|
||
MINIAPP_ICON_DEFAULTS['merchant_home_stat_bg'] = 'beijing/shangjiaduan/stat_card_bg.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_recharge_member'] = f'{ICON_FOLDER}/fighter_recharge_member.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_recharge_deposit'] = f'{ICON_FOLDER}/fighter_recharge_deposit.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_recharge_vip_bg'] = f'{ICON_FOLDER}/fighter_recharge_vip_bg.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_deposit_bg'] = f'{ICON_FOLDER}/fighter_deposit_bg.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_deposit_hero'] = f'{ICON_FOLDER}/fighter_deposit_hero.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_order_pending'] = f'{ICON_FOLDER}/fighter_order_pending.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_order_settling'] = f'{ICON_FOLDER}/fighter_order_settling.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_order_done'] = f'{ICON_FOLDER}/fighter_order_done.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_order_closed'] = f'{ICON_FOLDER}/fighter_order_closed.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_trade_commission'] = f'{ICON_FOLDER}/fighter_trade_commission.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_trade_withdraw'] = f'{ICON_FOLDER}/fighter_trade_withdraw.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_trade_settle'] = f'{ICON_FOLDER}/fighter_trade_settle.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_trade_deduct'] = f'{ICON_FOLDER}/fighter_trade_deduct.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_trade_recharge'] = f'{ICON_FOLDER}/fighter_trade_recharge.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_invite_subordinate'] = f'{ICON_FOLDER}/fighter_invite_subordinate.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_invite_poster'] = f'{ICON_FOLDER}/fighter_invite_poster.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_invite_code'] = f'{ICON_FOLDER}/fighter_invite_code.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_kuaishou_cash'] = f'{ICON_FOLDER}/fighter_kuaishou_cash.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_follow_kuaishou'] = 'beijing/tubiao/grzx_guanzhualong.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_copy'] = 'beijing/guanshiduan/icon-copy.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_edit'] = 'beijing/dashouduan/dashoutubiaobeijing/icon-edit.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_qiepian'] = f'{ICON_FOLDER}/fighter_mine_qiepian.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_penalty_tip'] = f'{ICON_FOLDER}/fighter_mine_penalty_tip.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_kefu'] = 'beijing/tubiao/grzx_kefu.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_shangjia'] = 'beijing/tubiao/grzx_shangjia.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_complaint_record'] = 'beijing/guanshiduan/icon-contact.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_punish'] = 'beijing/dashouduan/dashoutubiaobeijing/icon-punish.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_medal'] = 'beijing/dashouduan/dashoutubiaobeijing/icon-medal.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_book'] = 'beijing/dashouduan/dashoutubiaobeijing/icon-book.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_rank'] = 'beijing/dashouduan/dashoutubiaobeijing/icon-rank.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_invite'] = 'beijing/guanshiduan/icon-invite.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_contact'] = 'beijing/guanshiduan/icon-contact.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_record'] = 'beijing/guanshiduan/icon-record.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_kaohe_dafen'] = 'beijing/kaohe/daofen.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_kaohe_jilu'] = 'beijing/kaohe/jilu.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_kaohe_zhongxin'] = 'beijing/kaohe/zhongxin.png'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_dashou_auth'] = 'beijing/tubiao/grzx_dashou.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_clear'] = 'beijing/tubiao/grzx_qingchu.jpg'
|
||
MINIAPP_ICON_DEFAULTS['fighter_mine_switch'] = f'{ICON_FOLDER}/fighter_mine_switch.png'
|
||
MINIAPP_ICON_DEFAULTS['mine_pindao'] = 'beijing/tubiao/grzx_pindao.jpg'
|
||
MINIAPP_ICON_DEFAULTS['cuser_mine_kefu'] = 'beijing/tubiao/grzx_kefu.jpg'
|
||
# 邀请默认用邀请图标,避免与客服同图
|
||
MINIAPP_ICON_DEFAULTS['cuser_mine_invite'] = 'beijing/guanshiduan/icon-invite.png'
|
||
# 推荐的人:用下级/人员图标,勿与关注快手同图;勿用可能不存在的 chengxutubiao 占位 png
|
||
MINIAPP_ICON_DEFAULTS['cuser_mine_invitees'] = 'beijing/guanshiduan/icon-sub.png'
|
||
MINIAPP_ICON_DEFAULTS['guanshi_poster_bg'] = 'beijing/haibaobeijing.jpg'
|
||
MINIAPP_ICON_DEFAULTS['zuzhang_poster_bg'] = 'beijing/zuzhangbeijing.jpg'
|
||
# 点单端推荐官海报:独立路径,禁止复用管事/打手背景
|
||
MINIAPP_ICON_DEFAULTS['cuser_poster_bg'] = 'beijing/haibao/cuser_poster_bg.jpg'
|
||
|
||
POSTER_BG_FIELDS = {
|
||
'guanshi_bg': 'guanshi_poster_bg',
|
||
'zuzhang_bg': 'zuzhang_poster_bg',
|
||
'cuser_bg': 'cuser_poster_bg',
|
||
}
|
||
POSTER_BG_DEFAULTS = {
|
||
'guanshi_bg': 'beijing/haibaobeijing.jpg',
|
||
'zuzhang_bg': 'beijing/zuzhangbeijing.jpg',
|
||
'cuser_bg': 'beijing/haibao/cuser_poster_bg.jpg',
|
||
}
|
||
POSTER_FOLDER = 'beijing/haibao'
|
||
POSTER_ICON_KEYS = frozenset(POSTER_BG_FIELDS.values())
|
||
|
||
# 仅后台上传后才下发给小程序(页面大背景等)
|
||
CONFIG_ONLY_DELIVERY_KEYS = frozenset([
|
||
'fighter_recharge_vip_bg',
|
||
'fighter_deposit_bg',
|
||
'fighter_deposit_hero',
|
||
])
|
||
|
||
|
||
def default_icon_path(icon_key: str) -> str:
|
||
return MINIAPP_ICON_DEFAULTS.get(icon_key) or f'{ICON_FOLDER}/{icon_key}.png'
|
||
|
||
|
||
def get_miniapp_icons_dict(club_id: str) -> dict:
|
||
from config.models import ClubMiniappIcon
|
||
|
||
rows = {
|
||
r.icon_key: r
|
||
for r in ClubMiniappIcon.query.filter(club_id=club_id, is_active=True)
|
||
}
|
||
result = {}
|
||
for key, _label in MINIAPP_ICON_META:
|
||
row = rows.get(key)
|
||
if row and row.is_uploaded and (row.image_path or '').strip():
|
||
result[key] = row.image_path.strip()
|
||
continue
|
||
if key in CONFIG_ONLY_DELIVERY_KEYS:
|
||
continue
|
||
if row and (row.image_path or '').strip():
|
||
result[key] = row.image_path.strip()
|
||
else:
|
||
result[key] = default_icon_path(key)
|
||
return result
|
||
|
||
|
||
def get_pindao_payload(club_id: str) -> dict:
|
||
from config.models import ClubPindao, ClubPindaoImage
|
||
|
||
row = ClubPindao.query.filter(club_id=club_id, is_active=True).first()
|
||
if not row:
|
||
return {'channel_no': '', 'title': '频道', 'images': []}
|
||
images = [
|
||
img.image_path
|
||
for img in ClubPindaoImage.query.filter(club_id=club_id).order_by('sort_order', 'id')
|
||
if img.image_path
|
||
]
|
||
return {
|
||
'channel_no': row.channel_no or '',
|
||
'title': row.title or '频道',
|
||
'images': images,
|
||
}
|
||
|
||
|
||
def get_poster_payload(club_id: str) -> dict:
|
||
"""各俱乐部推广海报背景相对路径(后台上传后覆盖默认)。"""
|
||
from config.models import ClubMiniappIcon
|
||
|
||
rows = {
|
||
r.icon_key: r
|
||
for r in ClubMiniappIcon.query.filter(club_id=club_id, is_active=True)
|
||
}
|
||
result = {}
|
||
for field, icon_key in POSTER_BG_FIELDS.items():
|
||
default = POSTER_BG_DEFAULTS[field]
|
||
row = rows.get(icon_key)
|
||
if row and row.is_uploaded and (row.image_path or '').strip():
|
||
result[field] = row.image_path.strip()
|
||
elif field == 'cuser_bg':
|
||
# 点单端未上传时不回落到管事背景,避免错图
|
||
result[field] = (row.image_path.strip() if row and (row.image_path or '').strip() else '') or default
|
||
else:
|
||
result[field] = default
|
||
return result
|
||
|
||
|
||
def build_miniapp_assets_payload(request) -> dict:
|
||
club_id = _display_club_id(request)
|
||
return {
|
||
'icons': get_miniapp_icons_dict(club_id),
|
||
'pindao': get_pindao_payload(club_id),
|
||
'poster': get_poster_payload(club_id),
|
||
}
|
||
|
||
|
||
def seed_miniapp_icons_for_club(club_id: str, overwrite: bool = False) -> int:
|
||
from config.models import ClubMiniappIcon
|
||
|
||
created = 0
|
||
for key, label in MINIAPP_ICON_META:
|
||
path = default_icon_path(key)
|
||
row = ClubMiniappIcon.query.filter(club_id=club_id, icon_key=key).first()
|
||
if row:
|
||
if overwrite:
|
||
row.label = label
|
||
row.image_path = path
|
||
row.is_active = True
|
||
row.save(update_fields=['label', 'image_path', 'is_active', 'UpdateTime'])
|
||
continue
|
||
ClubMiniappIcon.query.create(
|
||
club_id=club_id,
|
||
icon_key=key,
|
||
label=label,
|
||
image_path=path,
|
||
is_active=True,
|
||
)
|
||
created += 1
|
||
return created
|
||
|
||
|
||
def copy_miniapp_assets(template_club_id: str, new_club_id: str):
|
||
from config.models import ClubMiniappIcon, ClubPindao, ClubPindaoImage
|
||
|
||
for row in ClubMiniappIcon.query.filter(club_id=template_club_id):
|
||
if ClubMiniappIcon.query.filter(club_id=new_club_id, icon_key=row.icon_key).exists():
|
||
continue
|
||
ClubMiniappIcon.query.create(
|
||
club_id=new_club_id,
|
||
icon_key=row.icon_key,
|
||
label=row.label,
|
||
image_path=row.image_path,
|
||
description=row.description,
|
||
is_active=row.is_active,
|
||
is_uploaded=row.is_uploaded,
|
||
)
|
||
|
||
src_pindao = ClubPindao.query.filter(club_id=template_club_id).first()
|
||
if not src_pindao or ClubPindao.query.filter(club_id=new_club_id).exists():
|
||
return
|
||
new_pindao = ClubPindao.query.create(
|
||
club_id=new_club_id,
|
||
channel_no=src_pindao.channel_no,
|
||
title=src_pindao.title,
|
||
is_active=src_pindao.is_active,
|
||
)
|
||
for img in ClubPindaoImage.query.filter(club_id=template_club_id).order_by('sort_order', 'id'):
|
||
ClubPindaoImage.query.create(
|
||
club_id=new_club_id,
|
||
pindao=new_pindao,
|
||
image_path=img.image_path,
|
||
sort_order=img.sort_order,
|
||
)
|