fix: 迁移子会员时长按总会员有效覆盖累加,避免少加天数
EOF Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -593,8 +593,74 @@ def _find_user_huiyuangoumai(uid: str, huiyuan_id: str, *, for_update: bool = Fa
|
||||
return qs.first()
|
||||
|
||||
|
||||
def _latest_effective_cover_until(uid: str, huiyuan_id: str, club_id: str, *, goumai_row=None):
|
||||
"""
|
||||
目标店对该会员类型的有效覆盖到期:
|
||||
- 自己开通的该子会员/总会员未到期
|
||||
- 或任意未到期总会员包含该子会员
|
||||
用于迁移累加:总会员覆盖剩 10 天 + 迁入同子会员 10 天 → 子会员落到 20 天。
|
||||
"""
|
||||
from jituan.services.huiyuan_bundle import (
|
||||
_included_huiyuan_id_set,
|
||||
_membership_record_active,
|
||||
expand_huiyuan_id_variants,
|
||||
huiyuan_ids_match,
|
||||
is_bundle_huiyuan,
|
||||
normalize_huiyuan_id,
|
||||
resolve_bundle_included_ids,
|
||||
)
|
||||
from products.models import Huiyuangoumai
|
||||
|
||||
now = _now_aware()
|
||||
hid = normalize_huiyuan_id(huiyuan_id)
|
||||
if not hid:
|
||||
return None
|
||||
req_set = {hid, hid.lstrip('0') or '0'}
|
||||
for vid in expand_huiyuan_id_variants(hid):
|
||||
req_set.add(vid)
|
||||
req_set.add(vid.lstrip('0') or '0')
|
||||
|
||||
latest = None
|
||||
|
||||
def bump(dt):
|
||||
nonlocal latest
|
||||
exp = _aware(dt)
|
||||
if not exp or exp <= now:
|
||||
return
|
||||
if latest is None or exp > latest:
|
||||
latest = exp
|
||||
|
||||
row = goumai_row
|
||||
if row is None:
|
||||
row = _find_user_huiyuangoumai(uid, hid)
|
||||
if row is not None and int(row.huiyuan_zhuangtai or 0) == 1:
|
||||
bump(row.daoqi_time)
|
||||
|
||||
for rec in Huiyuangoumai.query.filter(yonghu_id=str(uid)):
|
||||
if not _membership_record_active(rec):
|
||||
continue
|
||||
if huiyuan_ids_match(rec.huiyuan_id, hid):
|
||||
bump(rec.daoqi_time)
|
||||
continue
|
||||
if not is_bundle_huiyuan(rec.huiyuan_id):
|
||||
continue
|
||||
included = resolve_bundle_included_ids(
|
||||
rec.huiyuan_id,
|
||||
club_id=club_id,
|
||||
yonghu_id=uid,
|
||||
record_club_id=getattr(rec, 'club_id', None),
|
||||
)
|
||||
if req_set & _included_huiyuan_id_set(included):
|
||||
bump(rec.daoqi_time)
|
||||
return latest
|
||||
|
||||
|
||||
def _add_huiyuan_duration(*, to_uid: str, to_club: str, huiyuan_id: str, remain, jieshao: str, is_trial: bool, has_used_trial: bool):
|
||||
"""给目标用户对应会员加时长(已有则累加剩余,否则从现在起算)。"""
|
||||
"""给目标用户对应会员加时长。
|
||||
|
||||
累加基数 = max(现在, 该会员自身到期, 覆盖它的总会员到期)。
|
||||
避免:目标已有总会员覆盖子会员 10 天,迁入同子会员 10 天却只得到约 10 天(应为 20)。
|
||||
"""
|
||||
from products.models import Huiyuangoumai
|
||||
|
||||
now = _now_aware()
|
||||
@@ -611,9 +677,12 @@ def _add_huiyuan_duration(*, to_uid: str, to_club: str, huiyuan_id: str, remain,
|
||||
'zhuangtai': dst.huiyuan_zhuangtai,
|
||||
'club_id': dst.club_id,
|
||||
}
|
||||
dst_exp = _aware(dst.daoqi_time)
|
||||
base = dst_exp if (dst_exp and dst_exp > now and int(dst.huiyuan_zhuangtai or 0) == 1) else now
|
||||
|
||||
cover = _latest_effective_cover_until(to_uid, hid, to_club, goumai_row=dst)
|
||||
base = cover if (cover and cover > now) else now
|
||||
exp = base + remain
|
||||
|
||||
if dst:
|
||||
dst.daoqi_time = exp
|
||||
dst.huiyuan_zhuangtai = 1
|
||||
dst.club_id = to_club
|
||||
@@ -622,7 +691,6 @@ def _add_huiyuan_duration(*, to_uid: str, to_club: str, huiyuan_id: str, remain,
|
||||
dst.save(update_fields=['daoqi_time', 'huiyuan_zhuangtai', 'club_id', 'jieshao', 'UpdateTime'])
|
||||
return exp, before_dst
|
||||
|
||||
exp = now + remain
|
||||
try:
|
||||
Huiyuangoumai.query.create(
|
||||
huiyuan_id=hid,
|
||||
@@ -644,9 +712,9 @@ def _add_huiyuan_duration(*, to_uid: str, to_club: str, huiyuan_id: str, remain,
|
||||
'zhuangtai': dst2.huiyuan_zhuangtai,
|
||||
'club_id': dst2.club_id,
|
||||
}
|
||||
dst_exp = _aware(dst2.daoqi_time)
|
||||
base = dst_exp if (dst_exp and dst_exp > now and int(dst2.huiyuan_zhuangtai or 0) == 1) else now
|
||||
exp = base + remain
|
||||
cover2 = _latest_effective_cover_until(to_uid, hid, to_club, goumai_row=dst2)
|
||||
base2 = cover2 if (cover2 and cover2 > now) else now
|
||||
exp = base2 + remain
|
||||
dst2.daoqi_time = exp
|
||||
dst2.huiyuan_zhuangtai = 1
|
||||
dst2.club_id = to_club
|
||||
|
||||
Reference in New Issue
Block a user