diff --git a/jituan/services/club_migrate.py b/jituan/services/club_migrate.py index 59fb956..8b77fa7 100644 --- a/jituan/services/club_migrate.py +++ b/jituan/services/club_migrate.py @@ -980,6 +980,12 @@ def serialize_plan(plan: ClubMigratePlan) -> dict: def serialize_token(token_row: ClubMigrateToken) -> dict: + qr = (token_row.qrcode_url or '').strip() + if qr and not qr.startswith('http'): + from django.conf import settings + cos_domain = getattr(settings, 'COS_DOMAIN', '').rstrip('/') + if cos_domain: + qr = f'{cos_domain}/{qr.lstrip("/")}' return { 'token': token_row.token, 'scene': scene_for_token(token_row.token), @@ -987,7 +993,7 @@ def serialize_token(token_row: ClubMigrateToken) -> dict: 'from_club_id': token_row.from_club_id, 'to_club_id': token_row.to_club_id, 'status': token_row.status, - 'qrcode_url': token_row.qrcode_url or '', + 'qrcode_url': qr, 'expire_at': token_row.expire_at.isoformat() if token_row.expire_at else '', 'asset_snapshot': token_row.asset_snapshot or {}, } diff --git a/jituan/services/club_migrate_qr.py b/jituan/services/club_migrate_qr.py index 4eba410..074220f 100644 --- a/jituan/services/club_migrate_qr.py +++ b/jituan/services/club_migrate_qr.py @@ -74,16 +74,17 @@ def generate_migrate_qrcode(*, to_club_id: str, token: str) -> Tuple[str, str]: oss_path = f"club_migrate/{club_id}/{filename}" file_obj = io.BytesIO(wx_resp.content) try: - full_url = upload_to_oss(file_obj, oss_path) + full_url = upload_to_oss(file_obj, oss_path, content_type='image/png') except Exception as e: logger.exception('migrate qr upload fail: %s', e) return '', f'上传小程序码失败: {e}' if not full_url: return '', '上传小程序码失败' + # 前端保存相册必须用 https 完整链;相对路径在 oss 未就绪时会保存失败 + if str(full_url).startswith('http'): + return str(full_url), '' cos_domain = getattr(settings, 'COS_DOMAIN', '').rstrip('/') - if cos_domain and full_url.startswith(cos_domain): - relative_path = full_url.replace(f'{cos_domain}/', '', 1) - else: - relative_path = oss_path - return relative_path, '' + if cos_domain: + return f'{cos_domain}/{str(full_url).lstrip("/")}', '' + return str(full_url), '' diff --git a/jituan/views_club_migrate.py b/jituan/views_club_migrate.py index 87d7635..a22a902 100644 --- a/jituan/views_club_migrate.py +++ b/jituan/views_club_migrate.py @@ -231,12 +231,21 @@ class ClubMigrateConfirmView(APIView): password = str(request.data.get('password') or '').strip() if not token: return Response({'code': 400, 'msg': '缺少令牌'}) + # 必须在目标店小程序确认(防止源店误点确认) + club_id = _resolve_club_id(request) + from jituan.models import ClubMigrateToken + row = ClubMigrateToken.query.filter(token=token).first() + if row and club_id and str(row.to_club_id) != club_id: + return Response({ + 'code': 400, + 'msg': f'请用目标店小程序({row.to_club_id})扫码确认,当前店={club_id}', + }) data, err = migrate_svc.confirm_migrate( token=token, password=password, to_uid=str(request.user.UserUID), client_meta={ - 'club_id': _user_club(request.user), + 'club_id': club_id or _user_club(request.user), 'ip': request.META.get('REMOTE_ADDR', ''), }, )