fix: 加固会员回滚命令,有未过期充值单绝不收回
增加 repair 指纹校验;减会员后重新付费不再误收。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -673,6 +673,77 @@ def user_has_active_czjilu_entitlement(yonghu_id, huiyuan_id, club_id=None):
|
||||
return False
|
||||
|
||||
|
||||
def _paid_member_orders_for(yonghu_id, huiyuan_id):
|
||||
from jituan.services.huiyuan_bundle import huiyuan_ids_match
|
||||
|
||||
return [
|
||||
o for o in Czjilu.query.filter(
|
||||
yonghuid=yonghu_id,
|
||||
leixing=MEMBER_LEIXING,
|
||||
zhuangtai=MEMBER_PAID_STATUS,
|
||||
)
|
||||
if huiyuan_ids_match(o.huiyuan_id, huiyuan_id)
|
||||
]
|
||||
|
||||
|
||||
def order_purchase_days_locked(order, club_id=None):
|
||||
"""充值单锁定的有效天数(与履约/repair 同源)。"""
|
||||
cid = getattr(order, 'club_id', None) or club_id or CLUB_ID_DEFAULT
|
||||
is_trial = _order_is_trial_like(order, cid)
|
||||
days = int(getattr(order, 'purchase_days', None) or 0)
|
||||
if days <= 0:
|
||||
_, _, days = club_huiyuan_sellable(cid, order.huiyuan_id, is_trial=is_trial)
|
||||
return max(int(days or 0), 1)
|
||||
|
||||
|
||||
def is_suspected_bug_repair_restore(rec, since=None):
|
||||
"""
|
||||
Bug repair 指纹:UpdateTime 时将 daoqi 设为 UpdateTime+days,
|
||||
且存在匹配充值单的原定期限在 UpdateTime 之前已结束。
|
||||
正常续费:必有未过期充值单支撑,或 daoqi 与充值单原定期限一致。
|
||||
"""
|
||||
from jituan.services.huiyuan_bundle import _normalize_datetime_for_compare
|
||||
|
||||
updated = _normalize_datetime_for_compare(rec.UpdateTime)
|
||||
if since and updated < _normalize_datetime_for_compare(since):
|
||||
return None
|
||||
daoqi = _normalize_datetime_for_compare(rec.daoqi_time)
|
||||
gap_days = (daoqi - updated).days
|
||||
if gap_days < 1 or gap_days > 400:
|
||||
return None
|
||||
|
||||
for order in _paid_member_orders_for(rec.yonghu_id, rec.huiyuan_id):
|
||||
if _czjilu_entitlement_revoked(order):
|
||||
continue
|
||||
days = order_purchase_days_locked(order, rec.club_id)
|
||||
if abs(days - gap_days) > 2:
|
||||
continue
|
||||
if _czjilu_entitlement_end(order, rec.club_id) < updated:
|
||||
return order.dingdan_id
|
||||
return None
|
||||
|
||||
|
||||
def should_rollback_erroneous_membership(rec, since=None, require_repair_signature=True):
|
||||
"""
|
||||
是否应收回错误恢复的会员(保守策略,优先不误伤正常付费用户)。
|
||||
|
||||
硬性豁免:任意未过期已付充值单支撑 → 绝不收回。
|
||||
"""
|
||||
if rec.jiance_shifou_daoqi() or rec.huiyuan_zhuangtai != 1:
|
||||
return False, None
|
||||
if user_has_active_czjilu_entitlement(rec.yonghu_id, rec.huiyuan_id, rec.club_id):
|
||||
return False, '有未过期充值单支撑'
|
||||
orders = _paid_member_orders_for(rec.yonghu_id, rec.huiyuan_id)
|
||||
if not orders:
|
||||
return False, '无充值单不自动处理'
|
||||
if require_repair_signature:
|
||||
dingdan_id = is_suspected_bug_repair_restore(rec, since=since)
|
||||
if not dingdan_id:
|
||||
return False, '不符合 bug repair 指纹'
|
||||
return True, dingdan_id
|
||||
return True, None
|
||||
|
||||
|
||||
def expire_huiyuangoumai_record(rec, reason=''):
|
||||
"""将会员记录置为已过期(不删行,便于审计)。"""
|
||||
from jituan.services.huiyuan_bundle import _normalize_datetime_for_compare
|
||||
|
||||
Reference in New Issue
Block a user