diff --git a/shop/services/shenhe_config.py b/shop/services/shenhe_config.py index 44a7cb6..a3a7c32 100644 --- a/shop/services/shenhe_config.py +++ b/shop/services/shenhe_config.py @@ -1,43 +1,107 @@ """点单端商品展示 / 店铺审核模式:按俱乐部隔离。""" +import logging + +from django.db import OperationalError, ProgrammingError +from django.db.utils import DatabaseError + from jituan.constants import CLUB_ID_DEFAULT from shop.models import DianpuShangpinShenheShezhi +logger = logging.getLogger(__name__) + +_SCHEMA_ERRORS = (OperationalError, ProgrammingError, DatabaseError) + def _norm_club_id(club_id): return (club_id or CLUB_ID_DEFAULT).strip() or CLUB_ID_DEFAULT +def _legacy_row_values(*fields): + """ + 表尚未 migrate club_id 时:只查旧列,避免 SELECT club_id 导致 1054。 + """ + try: + return DianpuShangpinShenheShezhi.objects.values(*fields).first() + except _SCHEMA_ERRORS: + return None + + def get_or_create_shenhe_config(club_id): """获取或创建某俱乐部的审核展示配置。""" cid = _norm_club_id(club_id) - config, _ = DianpuShangpinShenheShezhi.objects.get_or_create( - club_id=cid, - defaults={ - 'kaiqi_shenhe': False, - 'zhi_kan_shenhe': True, - }, - ) - return config + try: + config, _ = DianpuShangpinShenheShezhi.objects.get_or_create( + club_id=cid, + defaults={ + 'kaiqi_shenhe': False, + 'zhi_kan_shenhe': True, + }, + ) + return config + except _SCHEMA_ERRORS as exc: + logger.error( + '审核配置表缺 club_id(请执行 migrate shop)。回落只读旧行。err=%s', + exc, + ) + # 尽量读旧全局行;读写接口若 save 仍会失败,需尽快 migrate + try: + obj = DianpuShangpinShenheShezhi.objects.defer('club_id').order_by('id').first() + if obj is not None: + return obj + except _SCHEMA_ERRORS: + pass + # 内存占位,避免后台整页 500 + from types import SimpleNamespace + return SimpleNamespace( + id=None, + club_id=cid, + kaiqi_shenhe=False, + zhi_kan_shenhe=True, + save=lambda *a, **k: (_ for _ in ()).throw( + RuntimeError('请先在服务器执行: python manage.py migrate shop') + ), + ) def is_zhi_kan_shenhe_enabled(club_id): """ 未绑店用户是否只看审核专用商品。 无配置时默认 True,保持历史行为。 + 未 migrate club_id 时回落旧表,绝不因缺列导致 /hqsp 500。 """ - config = DianpuShangpinShenheShezhi.query.filter( - club_id=_norm_club_id(club_id) - ).first() - if not config: - return True - return bool(getattr(config, 'zhi_kan_shenhe', True)) + try: + config = DianpuShangpinShenheShezhi.query.filter( + club_id=_norm_club_id(club_id) + ).first() + if not config: + return True + return bool(getattr(config, 'zhi_kan_shenhe', True)) + except _SCHEMA_ERRORS as exc: + logger.error( + 'is_zhi_kan_shenhe_enabled 缺列回落(请 migrate shop)。err=%s', + exc, + ) + row = _legacy_row_values('zhi_kan_shenhe') + if not row: + return True + return bool(row.get('zhi_kan_shenhe', True)) def is_kaiqi_shenhe_enabled(club_id): """店铺发布商品是否需平台审核。无配置默认 False。""" - config = DianpuShangpinShenheShezhi.query.filter( - club_id=_norm_club_id(club_id) - ).first() - if not config: - return False - return bool(config.kaiqi_shenhe) + try: + config = DianpuShangpinShenheShezhi.query.filter( + club_id=_norm_club_id(club_id) + ).first() + if not config: + return False + return bool(config.kaiqi_shenhe) + except _SCHEMA_ERRORS as exc: + logger.error( + 'is_kaiqi_shenhe_enabled 缺列回落(请 migrate shop)。err=%s', + exc, + ) + row = _legacy_row_values('kaiqi_shenhe') + if not row: + return False + return bool(row.get('kaiqi_shenhe', False))