diff --git a/jituan/services/huiyuan_bundle.py b/jituan/services/huiyuan_bundle.py index fbe6718..ffd5f4a 100644 --- a/jituan/services/huiyuan_bundle.py +++ b/jituan/services/huiyuan_bundle.py @@ -2,6 +2,25 @@ from products.models import Huiyuan, Huiyuangoumai +def normalize_huiyuan_id(huiyuan_id): + if huiyuan_id is None: + return '' + return str(huiyuan_id).strip() + + +def huiyuan_ids_match(a, b): + """会员 ID 等价比较(忽略首尾空格;001 与 1 视为相同)。""" + left = normalize_huiyuan_id(a) + right = normalize_huiyuan_id(b) + if not left or not right: + return False + if left == right: + return True + left_core = left.lstrip('0') or '0' + right_core = right.lstrip('0') or '0' + return left_core == right_core + + def get_bundle_included_ids(club_id, bundle_huiyuan_id): from jituan.models import ClubHuiyuanBundleInclude @@ -23,12 +42,11 @@ def is_bundle_huiyuan(huiyuan_id): def user_has_huiyuan_access(yonghu_id, required_huiyuan_id, club_id=None): - """用户是否可接要求 required_huiyuan_id 的会员单(含总会员覆盖)。""" - if not required_huiyuan_id: + """用户是否可接要求 required_huiyuan_id 的会员单(含总会员覆盖、体验会员)。""" + req = normalize_huiyuan_id(required_huiyuan_id) + if not req: return True - req = str(required_huiyuan_id).strip() - def _record_valid(rec): return ( rec @@ -36,12 +54,9 @@ def user_has_huiyuan_access(yonghu_id, required_huiyuan_id, club_id=None): and rec.huiyuan_zhuangtai == 1 ) - try: - direct = Huiyuangoumai.query.get(yonghu_id=yonghu_id, huiyuan_id=req) - if _record_valid(direct): + for rec in Huiyuangoumai.query.filter(yonghu_id=yonghu_id): + if _record_valid(rec) and huiyuan_ids_match(rec.huiyuan_id, req): return True - except Huiyuangoumai.DoesNotExist: - pass bundle_ids = set( Huiyuan.query.filter(is_bundle=True).values_list('huiyuan_id', flat=True) @@ -49,16 +64,62 @@ def user_has_huiyuan_access(yonghu_id, required_huiyuan_id, club_id=None): if not bundle_ids: return False + req_set = {req, req.lstrip('0') or '0'} for rec in Huiyuangoumai.query.filter(yonghu_id=yonghu_id, huiyuan_id__in=bundle_ids): if not _record_valid(rec): continue cid = club_id or rec.club_id or '' included = get_bundle_included_ids(cid, rec.huiyuan_id) - if req in {str(x) for x in included}: + included_set = set() + for x in included: + sx = normalize_huiyuan_id(x) + if sx: + included_set.add(sx) + included_set.add(sx.lstrip('0') or '0') + if req_set & included_set: return True return False +def resolve_order_membership_id(order_dict): + """从订单字段解析所需会员 ID(订单未写 huiyuan_id 时回退商品类型)。""" + membership_id = normalize_huiyuan_id(order_dict.get('MembershipID')) + if membership_id: + return membership_id + grab_req = int(order_dict.get('GrabRequirement') or 0) + if grab_req != 1: + return '' + leixing_id = order_dict.get('ProductTypeID') + if not leixing_id: + return '' + try: + from products.models import ShangpinLeixing + row = ShangpinLeixing.query.filter(id=leixing_id).values('huiyuan_id').first() + if row: + return normalize_huiyuan_id(row.get('huiyuan_id')) + except Exception: + pass + return '' + + +def resolve_grab_pool_member_display(order_dict, yonghu_id, club_id=None): + """ + 抢单池订单的会员展示字段(兼容旧小程序): + - 已有权限:yaoqiuleixing=0,hasRequiredMember=True + - 无权限:保持 yaoqiuleixing=1 + """ + grab_req = int(order_dict.get('GrabRequirement') or 0) + membership_id = resolve_order_membership_id(order_dict) + if grab_req != 1: + return grab_req, membership_id, True + if not membership_id: + return grab_req, '', True + has_access = user_has_huiyuan_access(yonghu_id, membership_id, club_id=club_id) + if has_access: + return 0, '', True + return 1, membership_id, False + + def enrich_clumber_item(record): """为 clumber 条目附加总会员覆盖的子会员 ID 列表(旧端忽略该字段)。""" item = { diff --git a/orders/views/dashou.py b/orders/views/dashou.py index be5b7f3..4ff6f73 100644 --- a/orders/views/dashou.py +++ b/orders/views/dashou.py @@ -296,7 +296,10 @@ class DashouDingdanHuoquView(APIView): club_id = resolve_effective_club_id(request, getattr(request, 'user', None)) identity_tag_map = batch_identity_tags(club_id, identity_pairs) if identity_pairs else {} - from jituan.services.huiyuan_bundle import user_has_huiyuan_access, build_user_clumber + from jituan.services.huiyuan_bundle import ( + build_user_clumber, + resolve_grab_pool_member_display, + ) yonghuid = request.user.UserUID # 12. 格式化返回数据 @@ -306,14 +309,9 @@ class DashouDingdanHuoquView(APIView): zid = order.get('AssignedID') info = zhiding_info.get(zid, {}) sj_uid = shangjia_id_map.get(oid) if order['Platform'] == 2 else None - grab_req = order['GrabRequirement'] or 0 - membership_id = order['MembershipID'] or '' - display_grab_req = grab_req - if grab_req == 1 and membership_id: - if user_has_huiyuan_access(yonghuid, membership_id, club_id=club_id): - # 前端用 yaoqiuleixing==1 判断是否展示「未开通会员」; - # 用户已有权接单时置 0,无需改小程序即可正常显示与抢单。 - display_grab_req = 0 + display_grab_req, display_huiyuan_id, has_required_member = ( + resolve_grab_pool_member_display(order, yonghuid, club_id=club_id) + ) formatted_list.append({ 'dingdan_id': order['OrderID'], 'zhuangtai': order['Status'], @@ -322,7 +320,9 @@ class DashouDingdanHuoquView(APIView): 'leixing_id': order['ProductTypeID'] or 0, 'tupian': order['ImageURL'] or '', 'yaoqiuleixing': display_grab_req, - 'huiyuan_id': membership_id if display_grab_req == 1 else '', + 'huiyuan_id': display_huiyuan_id, + 'hasRequiredMember': has_required_member, + 'has_required_member': has_required_member, 'yajin': float(order['CommissionReq']) if order['CommissionReq'] else 0.0, 'jieshao': order['Description'] or '', 'beizhu': order['Remark'] or '',