diff --git a/jituan/services/huiyuan_bundle.py b/jituan/services/huiyuan_bundle.py index d434fa0..fbe6718 100644 --- a/jituan/services/huiyuan_bundle.py +++ b/jituan/services/huiyuan_bundle.py @@ -63,8 +63,10 @@ def enrich_clumber_item(record): """为 clumber 条目附加总会员覆盖的子会员 ID 列表(旧端忽略该字段)。""" item = { 'huiyuanid': record.huiyuan_id, + 'huiyuan_id': record.huiyuan_id, 'huiyuanming': record.jieshao or f'会员{record.huiyuan_id}', 'daoqi': record.daoqi_time, + 'is_trial': bool(getattr(record, 'is_trial', False)), } if is_bundle_huiyuan(record.huiyuan_id): item['is_bundle'] = True @@ -74,6 +76,71 @@ def enrich_clumber_item(record): return item +def _append_bundle_sub_clumber(items, seen, record, base_item): + """总会员有效时,为抢单页展开子会员虚拟条目。""" + if not base_item.get('is_bundle'): + return + bundle_hid = str(record.huiyuan_id) + for sub_id in base_item.get('included_huiyuan_ids') or []: + sid = str(sub_id).strip() + if not sid or sid in seen: + continue + seen.add(sid) + items.append({ + 'huiyuanid': sid, + 'huiyuan_id': sid, + 'huiyuanming': base_item.get('huiyuanming', ''), + 'daoqi': base_item.get('daoqi'), + 'from_bundle': bundle_hid, + 'is_trial': bool(getattr(record, 'is_trial', False)), + }) + + +def build_user_clumber(yonghu_id): + """ + 构建抢单页可用的 clumber 列表。 + - 仅包含未过期且状态有效的会员(含体验会员) + - 总会员自动展开所覆盖的子会员 ID + - 同时返回 huiyuanid / huiyuan_id,兼容小程序各页面字段名 + """ + items = [] + seen = set() + for record in Huiyuangoumai.query.filter(yonghu_id=yonghu_id): + if record.jiance_shifou_daoqi(): + continue + if record.huiyuan_zhuangtai != 1: + continue + base = enrich_clumber_item(record) + hid = str(record.huiyuan_id) + if hid not in seen: + seen.add(hid) + items.append(base) + _append_bundle_sub_clumber(items, seen, record, base) + return items + + +def build_auth_clumber(yonghu_id): + """登录/注册返回的 clumber:保留状态字段,并补齐抢单页所需的 huiyuanid。""" + items = [] + seen = set() + for record in Huiyuangoumai.query.filter(yonghu_id=yonghu_id): + shifou_daoqi = record.jiance_shifou_daoqi() + base = enrich_clumber_item(record) + base.update({ + 'huiyuan_zhuangtai': record.huiyuan_zhuangtai, + 'daoqi_time': record.daoqi_time.isoformat() if record.daoqi_time else None, + 'shifou_daoqi': shifou_daoqi, + 'jieshao': record.jieshao, + }) + hid = str(record.huiyuan_id) + if hid not in seen: + seen.add(hid) + items.append(base) + if not shifou_daoqi and record.huiyuan_zhuangtai == 1: + _append_bundle_sub_clumber(items, seen, record, base) + return items + + def save_bundle_includes(club_id, bundle_huiyuan_id, included_ids): """保存俱乐部总会员包含的子会员(须为本俱乐部已上架的普通会员)。""" from jituan.models import ClubHuiyuanBundleInclude, ClubHuiyuanPrice diff --git a/orders/views/dashou.py b/orders/views/dashou.py index 47efacf..be5b7f3 100644 --- a/orders/views/dashou.py +++ b/orders/views/dashou.py @@ -296,6 +296,9 @@ 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 + yonghuid = request.user.UserUID + # 12. 格式化返回数据 formatted_list = [] for order in dingdan_list: @@ -303,6 +306,14 @@ 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 formatted_list.append({ 'dingdan_id': order['OrderID'], 'zhuangtai': order['Status'], @@ -310,8 +321,8 @@ class DashouDingdanHuoquView(APIView): 'dashou_fencheng': float(order['PlayerCommission']) if order['PlayerCommission'] else 0.0, 'leixing_id': order['ProductTypeID'] or 0, 'tupian': order['ImageURL'] or '', - 'yaoqiuleixing': order['GrabRequirement'] or 0, - 'huiyuan_id': order['MembershipID'] or '', + 'yaoqiuleixing': display_grab_req, + 'huiyuan_id': membership_id if display_grab_req == 1 else '', 'yajin': float(order['CommissionReq']) if order['CommissionReq'] else 0.0, 'jieshao': order['Description'] or '', 'beizhu': order['Remark'] or '', @@ -348,6 +359,7 @@ class DashouDingdanHuoquView(APIView): 'current_page': page, 'page_size': page_size, 'total_pages': (total + page_size - 1) // page_size, + 'clumber': build_user_clumber(yonghuid), } }) diff --git a/users/views/auth.py b/users/views/auth.py index 36d8c64..7f247c4 100644 --- a/users/views/auth.py +++ b/users/views/auth.py @@ -653,20 +653,11 @@ class DashouZhuceView(APIView): } # 查询并处理会员列表 (clumber) - # 使用当前用户的yonghuid进行查询 - huiyuan_goumai_list = [] - if not is_new: # 如果是新用户,直接返回空列表,无需查询 - goumai_records = Huiyuangoumai.query.filter(yonghu_id=current_user.UserUID) - for record in goumai_records: - # 调用方法检查是否到期,此方法内部会更新状态 - shifou_daoqi = record.jiance_shifou_daoqi() - huiyuan_goumai_list.append({ - 'huiyuan_id': record.huiyuan_id, - 'huiyuan_zhuangtai': record.huiyuan_zhuangtai, - 'daoqi_time': record.daoqi_time.isoformat() if record.daoqi_time else None, - 'shifou_daoqi': shifou_daoqi, - 'jieshao': record.jieshao - }) + from jituan.services.huiyuan_bundle import build_auth_clumber + if is_new: + huiyuan_goumai_list = [] + else: + huiyuan_goumai_list = build_auth_clumber(current_user.UserUID) data['clumber'] = huiyuan_goumai_list return data @@ -1234,19 +1225,8 @@ class WechatLoginAndDashouRegisterView(APIView): } # 查询并处理会员列表 (clumber) - # 使用当前用户的yonghuid进行查询 - huiyuan_goumai_list = [] - goumai_records = Huiyuangoumai.query.filter(yonghu_id=dashou_profile.user.UserUID) - for record in goumai_records: - # 调用方法检查是否到期,此方法内部会更新状态 - shifou_daoqi = record.jiance_shifou_daoqi() - huiyuan_goumai_list.append({ - 'huiyuan_id': record.huiyuan_id, - 'huiyuan_zhuangtai': record.huiyuan_zhuangtai, - 'daoqi_time': record.daoqi_time.isoformat() if record.daoqi_time else None, - 'shifou_daoqi': shifou_daoqi, - 'jieshao': record.jieshao - }) + from jituan.services.huiyuan_bundle import build_auth_clumber + huiyuan_goumai_list = build_auth_clumber(dashou_profile.user.UserUID) data['clumber'] = huiyuan_goumai_list return data @@ -1442,20 +1422,12 @@ class WechatLoginAndGuanshiRegisterView(APIView): 'zaixianzhuangtai': dashou_profile.zaixianzhuangtai, 'dashouzhuangtai': dashou_profile.zhuangtai, } - huiyuan_list = [] + from jituan.services.huiyuan_bundle import build_auth_clumber try: - records = Huiyuangoumai.query.filter(yonghu_id=dashou_profile.user.UserUID) - for record in records: - shifou_daoqi = record.jiance_shifou_daoqi() - huiyuan_list.append({ - 'huiyuan_id': record.huiyuan_id, - 'huiyuan_zhuangtai': record.huiyuan_zhuangtai, - 'daoqi_time': record.daoqi_time.isoformat() if record.daoqi_time else None, - 'shifou_daoqi': shifou_daoqi, - 'jieshao': record.jieshao - }) + huiyuan_list = build_auth_clumber(dashou_profile.user.UserUID) except Exception as e: logger.warning(f"获取会员列表失败: {e}") + huiyuan_list = [] data['clumber'] = huiyuan_list return data @@ -1676,20 +1648,12 @@ class GuanshiRegisterView(APIView): } # 会员列表 - huiyuan_list = [] + from jituan.services.huiyuan_bundle import build_auth_clumber try: - records = Huiyuangoumai.query.filter(yonghu_id=dashou_profile.user.UserUID) - for record in records: - shifou_daoqi = record.jiance_shifou_daoqi() - huiyuan_list.append({ - 'huiyuan_id': record.huiyuan_id, - 'huiyuan_zhuangtai': record.huiyuan_zhuangtai, - 'daoqi_time': record.daoqi_time.isoformat() if record.daoqi_time else None, - 'shifou_daoqi': shifou_daoqi, - 'jieshao': record.jieshao - }) + huiyuan_list = build_auth_clumber(dashou_profile.user.UserUID) except Exception as e: logger.warning(f"获取会员列表失败: {e}") + huiyuan_list = [] data['clumber'] = huiyuan_list return data diff --git a/users/views/user_info.py b/users/views/user_info.py index c709603..aa1c499 100644 --- a/users/views/user_info.py +++ b/users/views/user_info.py @@ -337,22 +337,11 @@ class DashouXinxiAPIView(APIView): 'chenghao': dashou_profile.chenghao or '', } - # 4. 查询会员信息(原有逻辑) - huiyuan_list = [] + # 4. 查询会员信息(含体验会员、总会员子类型展开) try: - huiyuan_records = Huiyuangoumai.query.filter( - yonghu_id=yonghuid - ).select_related() - - for record in huiyuan_records: - # 过期检测会同步更新 huiyuan_zhuangtai - if record.jiance_shifou_daoqi(): - continue - if record.huiyuan_zhuangtai == 1: - from jituan.services.huiyuan_bundle import enrich_clumber_item - huiyuan_list.append(enrich_clumber_item(record)) - except Exception as e: - # 会员信息查询失败不影响主要功能,返回空列表 + from jituan.services.huiyuan_bundle import build_user_clumber + huiyuan_list = build_user_clumber(yonghuid) + except Exception: huiyuan_list = [] data['clumber'] = huiyuan_list