feat: 打手规则图支持多张并修复小程序兜底路径

This commit is contained in:
XingQue committed 2026-08-10 19:01:34 +08:00
1 parent 712d497672
commit 5dbd3579c8
5 files changed
+66 -16

No files matched your search

@@ -0,0 +1,26 @@
from django.db import migrations, models
class Migration(migrations.Migration):
"""
打手规则图(ImageType=1)、关注快手(3) 需支持多图;
原先 unique(club_id, ImageType) 会挡掉第二条。默认头像(2)仍由业务层 upsert 保单条。
"""
dependencies = [
('config', '0012_miniapp_script'),
]
operations = [
migrations.AlterUniqueTogether(
name='tupianpeizhi',
unique_together=set(),
),
migrations.AddIndex(
model_name='tupianpeizhi',
index=models.Index(
fields=['club_id', 'ImageType'],
name='tupian_club_type_idx',
),
),
]
+4 -1
View File
@@ -60,7 +60,10 @@ class Tupianpeizhi(QModel):
db_table = 'tupianpeizhi'
verbose_name = '配置图片'
verbose_name_plural = '配置图片'
# ImageType 1/2 每俱乐部唯一;3(关注快手) 允许多张
# ImageType 2(默认头像) 业务层保单条;1(打手规则)/3(关注快手) 允许多张
indexes = [
models.Index(fields=['club_id', 'ImageType'], name='tupian_club_type_idx'),
]
class Szjilu(QModel):
+7 -4
View File
@@ -66,7 +66,7 @@ class GetDynamicConfigView(APIView):
def post(self, request):
try:
from jituan.services.display_config import get_tupianpeizhi_url
from jituan.services.display_config import get_tupianpeizhi_url, get_tupianpeizhi_urls
from jituan.services.miniapp_assets import build_miniapp_assets_payload
@@ -77,10 +77,12 @@ class GetDynamicConfigView(APIView):
cos_region = getattr(settings, 'COS_REGION', 'ap-shanghai')
goeasy_host = 'hangzhou.goeasy.io'
goeasy_appkey = getattr(settings, 'GOEASY_APPKEY', '')
rule_img = get_tupianpeizhi_url(request, 1)
rule_imgs = get_tupianpeizhi_urls(request, 1)
avatar_img = get_tupianpeizhi_url(request, 2)
morentouxiang = avatar_img or 'beijing/morentouxiang.jpg'
dashouguize = rule_img or 'a_long/dashouguize.jpg'
# 兼容旧字段:首图;无配置时不返回已 404 的 a_long 默认路径
dashouguize = rule_imgs[0] if rule_imgs else ''
dashouguize_list = rule_imgs
from jituan.services.club_context import resolve_club_id_from_request
from jituan.services.wecom_kefu import miniapp_kefu_payload
@@ -103,7 +105,8 @@ class GetDynamicConfigView(APIView):
},
"otherConfig": {
"morentouxiang": morentouxiang,
"dashouguize": dashouguize
"dashouguize": dashouguize,
"dashouguize_list": dashouguize_list,
},
"kefu": kefu_payload,
"miniappAssets": build_miniapp_assets_payload(request),
+23 -6
View File
@@ -104,12 +104,23 @@ def list_response_meta(request):
def get_tupianpeizhi_url(request, image_type):
"""按俱乐部读图片配置(各俱乐部独立,不回退 xq,避免串台)。"""
"""按俱乐部读图片配置(各俱乐部独立,不回退 xq,避免串台)。取该类型第一条。"""
urls = get_tupianpeizhi_urls(request, image_type)
return urls[0] if urls else ''
def get_tupianpeizhi_urls(request, image_type):
"""按俱乐部读某类型全部图片路径(相对 Key 或完整 URL),按 id 升序。"""
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 ''
rows = Tupianpeizhi.query.filter(club_id=club_id, ImageType=image_type).order_by('id')
out = []
for r in rows:
u = (r.ImageURL or '').strip()
if u:
out.append(u)
return out
TUPIAN_TYPE_LABELS = {
@@ -118,6 +129,9 @@ TUPIAN_TYPE_LABELS = {
3: '关注快手',
}
# 允许多张的 ImageType;其余走 upsert 单条
TUPIAN_MULTI_TYPES = frozenset({1, 3})
def list_tupianpeizhi_by_type(club_id, image_type):
from config.models import Tupianpeizhi
@@ -129,7 +143,7 @@ def list_tupianpeizhi_by_type(club_id, image_type):
def upsert_tupianpeizhi_single(club_id, image_type, image_url):
"""ImageType 1/2 每俱乐部仅一条;换图时删除旧 OSS 对象。"""
"""默认头像等单条类型:每俱乐部仅一条;换图时删除旧 OSS 对象。"""
from config.models import Tupianpeizhi
from utils.oss_utils import delete_from_oss
@@ -169,8 +183,11 @@ def copy_display_config(template_club_id, new_club_id):
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():
existing_tupian_types = {
r.ImageType for r in Tupianpeizhi.query.filter(club_id=new_club_id)
}
for row in Tupianpeizhi.query.filter(club_id=template_club_id).order_by('id'):
if row.ImageType in existing_tupian_types:
continue
Tupianpeizhi.query.create(
club_id=new_club_id,
+6 -5
View File
@@ -19,6 +19,7 @@ from jituan.services.display_config import (
LUNBO_PAGE_OPTIONS,
lunbo_image_type_for_page,
normalize_page_key,
TUPIAN_MULTI_TYPES,
TUPIAN_TYPE_LABELS,
upsert_tupianpeizhi_single,
)
@@ -183,7 +184,7 @@ class ClubTupianListView(APIView):
for t, label in TUPIAN_TYPE_LABELS.items():
data[str(t)] = {
'label': label,
'multi': t == 3,
'multi': t in TUPIAN_MULTI_TYPES,
'list': list_tupianpeizhi_by_type(club_id, t),
}
return Response({
@@ -247,19 +248,19 @@ class ClubTupianManageView(APIView):
return Response({'code': 400, 'msg': msg})
ext = os.path.splitext(file_obj.name)[1].lower() or '.jpg'
random_str = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
folder = 'guanzhu' if image_type == 3 else 'misc'
folder = 'guanzhu' if image_type == 3 else ('dashou_rule' if image_type == 1 else 'misc')
oss_file_path = f"beijing/{folder}/{club_id}_{random_str}{ext}"
if not upload_to_oss(file_obj, oss_file_path):
return Response({'code': 500, 'msg': '图片上传失败'})
if image_type in (1, 2):
upsert_tupianpeizhi_single(club_id, image_type, oss_file_path)
else:
if image_type in TUPIAN_MULTI_TYPES:
Tupianpeizhi.query.create(
club_id=club_id,
ImageType=image_type,
ImageURL=oss_file_path,
AccessCount=0,
)
else:
upsert_tupianpeizhi_single(club_id, image_type, oss_file_path)
return Response({'code': 0, 'msg': '上传成功', 'data': {'image_url': oss_file_path}})
return Response({'code': 400, 'msg': 'action 必须为 add 或 delete'})