fix: 停止每次拉单补回已删会员;后台移除标记充值单撤销
ddhq 不再全量 sync 充值单;jian_huiyuan 标记权益已撤销防复活;clumber 只读 huiyuangoumai。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -157,6 +157,8 @@ def _czjilu_grants_huiyuan_access(yonghu_id, required_huiyuan_id, club_id=None):
|
||||
leixing=MEMBER_LEIXING,
|
||||
zhuangtai=MEMBER_PAID_STATUS,
|
||||
).order_by('-CreateTime')[:30]:
|
||||
if _czjilu_entitlement_revoked(order):
|
||||
continue
|
||||
if not huiyuan_ids_match(order.huiyuan_id, req):
|
||||
continue
|
||||
cid = getattr(order, 'club_id', None) or club_id or CLUB_ID_DEFAULT
|
||||
@@ -357,28 +359,15 @@ def _build_clumber_from_paid_czjilu(yonghu_id):
|
||||
|
||||
def ensure_grab_pool_clumber(yonghu_id, club_id=None):
|
||||
"""
|
||||
【ddhq / dashouxinxi 展示专用】每次请求:先同步已付会员权益,再生成 clumber(体验=正式)。
|
||||
提现校验不得使用此函数。
|
||||
dddhq / dashouxinxi:只读 huiyuangoumai 生成 clumber(体验=正式)。
|
||||
不在每次请求全量 sync 充值单(后台移除后会被补回)。
|
||||
"""
|
||||
from jituan.services.member_recharge import sync_member_entitlements_for_user
|
||||
from jituan.services.member_recharge import repair_recent_paid_entitlements_if_missing
|
||||
|
||||
sync_member_entitlements_for_user(yonghu_id, limit=30)
|
||||
items = _build_user_clumber_core(yonghu_id)
|
||||
extra = _build_clumber_from_paid_czjilu(yonghu_id)
|
||||
if extra:
|
||||
seen_cores = set()
|
||||
for it in items:
|
||||
hid = normalize_huiyuan_id(it.get('huiyuanid') or it.get('huiyuan_id'))
|
||||
if hid:
|
||||
seen_cores.add(hid.lstrip('0') or '0')
|
||||
for it in extra:
|
||||
hid = normalize_huiyuan_id(it.get('huiyuanid') or it.get('huiyuan_id'))
|
||||
if not hid:
|
||||
continue
|
||||
core = hid.lstrip('0') or '0'
|
||||
if core not in seen_cores:
|
||||
items.append(it)
|
||||
seen_cores.add(core)
|
||||
if not items:
|
||||
repair_recent_paid_entitlements_if_missing(yonghu_id, limit=3)
|
||||
items = _build_user_clumber_core(yonghu_id)
|
||||
return bool(items), items
|
||||
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ MEMBER_PAID_STATUS = 3
|
||||
MEMBER_PENDING_STATUS = 9
|
||||
MEMBER_FAILED_STATUS = 8
|
||||
MEMBER_CANCELLED_STATUS = 2
|
||||
ENTITLEMENT_REVOKED_MARKER = '权益已撤销'
|
||||
MEMBER_JIFEN_CAP = 10
|
||||
MEMBER_JIFEN_TRIAL_GRANT = 5
|
||||
MEMBER_JIFEN_FORMAL_GRANT = 5
|
||||
@@ -629,10 +630,16 @@ def _add_first_buy_jifen(yonghuid):
|
||||
dashou.save(update_fields=['jifen'])
|
||||
|
||||
|
||||
def _czjilu_entitlement_revoked(order):
|
||||
return ENTITLEMENT_REVOKED_MARKER in (getattr(order, 'shuoming', None) or '')
|
||||
|
||||
|
||||
def repair_member_entitlement_if_paid(dingdan_id):
|
||||
order = Czjilu.query.filter(dingdan_id=dingdan_id, leixing=MEMBER_LEIXING).first()
|
||||
if not order or order.zhuangtai != MEMBER_PAID_STATUS or not order.huiyuan_id:
|
||||
return False
|
||||
if _czjilu_entitlement_revoked(order):
|
||||
return False
|
||||
|
||||
from jituan.services.huiyuan_bundle import huiyuan_ids_match
|
||||
for rec in Huiyuangoumai.query.filter(yonghu_id=order.yonghuid):
|
||||
@@ -684,24 +691,74 @@ def repair_member_entitlement_if_paid(dingdan_id):
|
||||
|
||||
|
||||
def sync_member_entitlements_for_user(yonghu_id, limit=15):
|
||||
"""读取打手资料/抢单池前,补写已支付但未落库的会员权益(幂等)。"""
|
||||
"""支付回调偶发失败时补权益;禁止在 dddhq 每次请求全量扫单(会覆盖后台移除)。"""
|
||||
return repair_recent_paid_entitlements_if_missing(yonghu_id, limit=limit)
|
||||
|
||||
|
||||
def repair_recent_paid_entitlements_if_missing(yonghu_id, limit=3):
|
||||
"""仅当用户当前无任何有效会员时,尝试补最近几笔已付单。"""
|
||||
from jituan.services.huiyuan_bundle import _membership_record_active
|
||||
|
||||
if not yonghu_id:
|
||||
return 0
|
||||
has_active = any(
|
||||
_membership_record_active(rec)
|
||||
for rec in Huiyuangoumai.query.filter(yonghu_id=yonghu_id)
|
||||
)
|
||||
if has_active:
|
||||
return 0
|
||||
|
||||
orders = Czjilu.query.filter(
|
||||
yonghuid=yonghu_id,
|
||||
leixing=MEMBER_LEIXING,
|
||||
zhuangtai=MEMBER_PAID_STATUS,
|
||||
).order_by('-CreateTime')[: max(1, int(limit or 15))]
|
||||
).order_by('-CreateTime')[: max(1, int(limit or 3))]
|
||||
fixed = 0
|
||||
for order in orders:
|
||||
if _czjilu_entitlement_revoked(order):
|
||||
continue
|
||||
try:
|
||||
if repair_member_entitlement_if_paid(order.dingdan_id):
|
||||
fixed += 1
|
||||
except Exception as exc:
|
||||
logger.error('同步会员权益失败 dingdan=%s err=%s', order.dingdan_id, exc)
|
||||
logger.error('补会员权益失败 dingdan=%s err=%s', order.dingdan_id, exc)
|
||||
return fixed
|
||||
|
||||
|
||||
def revoke_member_entitlement_admin(yonghu_id, huiyuan_id, club_id=None):
|
||||
"""后台移除会员:删 huiyuangoumai + 标记充值单已撤销,防止被 sync 补回。"""
|
||||
from jituan.services.huiyuan_bundle import huiyuan_ids_match, normalize_huiyuan_id
|
||||
|
||||
hid = normalize_huiyuan_id(huiyuan_id)
|
||||
if not hid:
|
||||
return 0, '缺少会员ID'
|
||||
|
||||
removed = 0
|
||||
for rec in list(Huiyuangoumai.query.filter(yonghu_id=yonghu_id)):
|
||||
if huiyuan_ids_match(rec.huiyuan_id, hid):
|
||||
rec.delete()
|
||||
removed += 1
|
||||
|
||||
for order in Czjilu.query.filter(
|
||||
yonghuid=yonghu_id,
|
||||
leixing=MEMBER_LEIXING,
|
||||
zhuangtai=MEMBER_PAID_STATUS,
|
||||
):
|
||||
if not huiyuan_ids_match(order.huiyuan_id, hid):
|
||||
continue
|
||||
if _czjilu_entitlement_revoked(order):
|
||||
continue
|
||||
note = (order.shuoming or '').strip()
|
||||
order.shuoming = _truncate_shuoming(
|
||||
f'{note} |{ENTITLEMENT_REVOKED_MARKER}|' if note else ENTITLEMENT_REVOKED_MARKER,
|
||||
)
|
||||
order.save(update_fields=['shuoming'])
|
||||
|
||||
if removed == 0:
|
||||
return 0, '该打手未购买此会员'
|
||||
return removed, None
|
||||
|
||||
|
||||
@transaction.atomic
|
||||
def fulfill_member_recharge(dingdan_id, paid_amount_yuan=None, source='callback'):
|
||||
locked = Czjilu.query.filter(dingdan_id=dingdan_id).select_for_update()
|
||||
|
||||
Reference in New Issue
Block a user