fix: 会员/图标换图生成新路径并删除旧OSS,避免CDN缓存导致不更新

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
XingQue
2026-07-26 02:52:52 +08:00
parent 7cb41bf4d7
commit 1234cff035
3 changed files with 56 additions and 14 deletions

View File

@@ -276,9 +276,13 @@ MEMBER_CARD_FOLDER = 'beijing/huiyuan'
def upload_member_card_image(request, huiyuan_id, field, file_obj):
"""上传会员充值页卡片图,写入 club_huiyuan_price.card_image / card_bg。"""
"""上传会员充值页卡片图,写入 club_huiyuan_price.card_image / card_bg。
每次上传生成新相对路径并删除旧图,避免「同名覆盖但 CDN/浏览器仍显示旧图」。
"""
import os
from utils.oss_utils import validate_image, upload_to_oss
import uuid
from utils.oss_utils import validate_image, upload_to_oss, delete_from_oss
if club_write_blocked(request):
return None, CLUB_WRITE_SCOPE_MSG
@@ -289,18 +293,36 @@ def upload_member_card_image(request, huiyuan_id, field, file_obj):
return None, msg
club_id = club_id_for_write(request)
ext = os.path.splitext(getattr(file_obj, 'name', '') or '')[1].lower()
if ext not in ('.png', '.jpg', '.jpeg', '.webp', '.gif'):
ext = '.png'
rel_path = f'{MEMBER_CARD_FOLDER}/{club_id}/{huiyuan_id}_{field}{ext}'
if not upload_to_oss(file_obj, rel_path):
return None, '上传 OSS 失败'
row = ClubHuiyuanPrice.query.filter(club_id=club_id, huiyuan_id=huiyuan_id).first()
if not row:
return None, '请先在当前俱乐部上架该会员'
ext = os.path.splitext(getattr(file_obj, 'name', '') or '')[1].lower()
if ext not in ('.png', '.jpg', '.jpeg', '.webp', '.gif'):
ext = '.png'
# 带时间戳+uuid保证 URL 变化,前端/CDN 不会命中旧缓存
stamp = uuid.uuid4().hex[:12]
rel_path = f'{MEMBER_CARD_FOLDER}/{club_id}/{huiyuan_id}_{field}_{stamp}{ext}'
if hasattr(file_obj, 'seek'):
try:
file_obj.seek(0)
except Exception:
pass
if not upload_to_oss(file_obj, rel_path):
return None, '上传 OSS 失败'
old_path = (getattr(row, field, None) or '').strip()
setattr(row, field, rel_path)
row.save(update_fields=[field, 'UpdateTime'])
if old_path and old_path != rel_path:
try:
delete_from_oss(old_path)
except Exception as e:
logger.warning('删除旧会员卡片图失败 club=%s hy=%s field=%s path=%s err=%s',
club_id, huiyuan_id, field, old_path, e)
return {field: rel_path, 'huiyuan_id': huiyuan_id}, None

View File

@@ -129,12 +129,20 @@ def list_tupianpeizhi_by_type(club_id, image_type):
def upsert_tupianpeizhi_single(club_id, image_type, image_url):
"""ImageType 1/2 每俱乐部仅一条。"""
"""ImageType 1/2 每俱乐部仅一条;换图时删除旧 OSS 对象"""
from config.models import Tupianpeizhi
from utils.oss_utils import delete_from_oss
row = Tupianpeizhi.query.filter(club_id=club_id, ImageType=image_type).first()
if row:
old = (row.ImageURL or '').strip()
row.ImageURL = image_url
row.save(update_fields=['ImageURL', 'UpdateTime'])
if old and old != image_url:
try:
delete_from_oss(old)
except Exception:
pass
else:
Tupianpeizhi.query.create(
club_id=club_id, ImageType=image_type, ImageURL=image_url, AccessCount=0,