diff --git a/jituan/services/admin_context.py b/jituan/services/admin_context.py index 0a4e741..98d2583 100644 --- a/jituan/services/admin_context.py +++ b/jituan/services/admin_context.py @@ -8,6 +8,12 @@ from jituan.constants import ( ) from jituan.models import AdminAssignment, Club +GROUP_MANAGE_ROLES = frozenset({ + 'GROUP_OWNER', + 'GROUP_SUPER_ADMIN', +}) + + def build_admin_club_context(user): """ 根据 admin_assignment + 超管推断后台登录后的俱乐部上下文。 @@ -30,16 +36,21 @@ def build_admin_club_context(user): for c in clubs_qs ] - if is_super and not assignments: + # 系统超管:始终集团视角 + 全部俱乐部(不受任职记录限制) + if is_super: + role_code = 'GROUP_SUPER_ADMIN' + if assignments: + primary = next((a for a in assignments if a.is_primary), assignments[0]) + role_code = primary.role_code or role_code return _pack( scope=DATA_SCOPE_ALL, club_id=CLUB_ID_DEFAULT, is_group_admin=True, - assignments=[], + assignments=assignments, clubs=all_clubs, can_switch_club=True, - role_code='GROUP_SUPER_ADMIN', - role_name=ADMIN_ROLE_LABELS['GROUP_SUPER_ADMIN'], + role_code=role_code, + role_name=ADMIN_ROLE_LABELS.get(role_code, role_code), ) if not assignments: @@ -55,7 +66,10 @@ def build_admin_club_context(user): ) primary = next((a for a in assignments if a.is_primary), assignments[0]) - has_group = any(a.club_id is None or a.data_scope == DATA_SCOPE_ALL for a in assignments) + has_group = any( + a.club_id is None or a.data_scope == DATA_SCOPE_ALL + for a in assignments + ) allowed_club_ids = {a.club_id for a in assignments if a.club_id} if has_group: @@ -82,6 +96,26 @@ def build_admin_club_context(user): ) +def can_manage_admin_assignments(user, permissions=None): + """是否可维护数据范围任职(超管 / 000001 / 集团超管任职)。""" + permissions = permissions or [] + is_super = ( + bool(user.IsSuperuser) + or user.UserType == 'admin' + or getattr(user, 'Phone', '') in SUPER_ADMIN_PHONES + ) + if is_super or '000001' in permissions: + return True + ctx = build_admin_club_context(user) + if ctx.get('is_group_admin') and ctx.get('role_code') in GROUP_MANAGE_ROLES: + return True + return any( + a.role_code in GROUP_MANAGE_ROLES + and (a.club_id is None or a.data_scope == DATA_SCOPE_ALL) + for a in AdminAssignment.query.filter(yonghuid=user.UserUID, status=1) + ) + + def _pack(scope, club_id, is_group_admin, assignments, clubs, can_switch_club, role_code, role_name): return { @@ -91,7 +125,10 @@ def _pack(scope, club_id, is_group_admin, assignments, clubs, can_switch_club, 'role_code': role_code, 'role_name': role_name, 'perm_source': 'gvsdsdk', - 'perm_note': '功能菜单权限仍由 gvsdsdk UserRole→Permission 控制;本表仅管数据范围', + 'perm_note': ( + '【功能权限】在「角色管理」绑 gvsdsdk 角色(如 caiwu、dingdan、000001);' + '【数据范围】在「数据范围配置」维护任职(能看/管哪个俱乐部)。两套独立。' + ), 'assignments': [ { 'club_id': a.club_id, diff --git a/jituan/views.py b/jituan/views.py index 8f8d8b1..985a81a 100644 --- a/jituan/views.py +++ b/jituan/views.py @@ -12,7 +12,7 @@ from rest_framework_simplejwt.tokens import RefreshToken from jituan.constants import SUPER_ADMIN_PHONES, ADMIN_ROLE_LABELS, CLUB_ID_DEFAULT, DATA_SCOPE_ALL, DATA_SCOPE_SINGLE from jituan.models import Club, AdminAssignment -from jituan.services.admin_context import build_admin_club_context +from jituan.services.admin_context import build_admin_club_context, can_manage_admin_assignments from jituan.services.wechat_login import login_or_register_by_club from jituan.services.caiwu_stats import build_caiwu_payload from jituan.services.szxx_stats import build_szxx_payload @@ -247,8 +247,8 @@ class ClubAdminAssignmentListView(APIView): action = (request.data.get('action') or 'list').strip() if action in ('create', 'update', 'delete'): - if not is_super or '000001' not in permissions: - return Response({'code': 403, 'msg': '仅超级管理员可维护任职数据'}, status=403) + if not can_manage_admin_assignments(user, permissions): + return Response({'code': 403, 'msg': '无权限维护任职数据(需超管或集团超管任职)'}, status=403) if action == 'create': yonghuid = (request.data.get('yonghuid') or '').strip() @@ -328,11 +328,11 @@ class ClubAdminAssignmentListView(APIView): 'msg': 'ok', 'data': { 'list': self._list_rows(qs.to_list()), - 'can_manage': is_super and '000001' in permissions, + 'can_manage': can_manage_admin_assignments(user, permissions), 'perm_note': ( - '【功能权限】在「角色管理」里给账号绑 gvsdsdk 角色(perm_code 如 caiwu、002ab);' + '【功能权限】在「角色管理」里给账号绑 gvsdsdk 角色(perm_code 如 caiwu、002ab、000001);' '【数据范围】在本页维护 admin_assignment(能看哪个俱乐部/集团汇总)。' - '两套独立,超管需有 000001 权限码。' + '两套独立:集团高管需在本页配「集团全部」任职 + 角色管理里勾功能菜单。' ), 'current_context': build_admin_club_context(user), }, diff --git a/orders/views.py b/orders/views.py index d3a61b1..60db18a 100644 --- a/orders/views.py +++ b/orders/views.py @@ -61,6 +61,7 @@ from .models import ( ) from jituan.services.club_config import get_commission_rate, get_commission_rate_object from jituan.services.club_context import resolve_club_id_from_request +from jituan.services.club_user import get_payment_openid from jituan.services.club_penalty import resolve_penalty_club_id from products.models import Shangpin, ShangpinLeixing, Huiyuangoumai from users.models import UserDashou, UserShangjia, UserBoss @@ -738,7 +739,7 @@ class CreateOrderView(APIView): # 获取当前用户信息 current_user = request.user laoban_yonghuid = getattr(current_user, 'UserUID', '') or getattr(current_user, 'yonghuid', '') - user_openid = getattr(current_user, 'OpenID', '') or getattr(current_user, 'openid', '') + user_openid, club_id = get_payment_openid(request, current_user, club_id) if not user_openid: return Response({'code': 10, 'msg': '用户openid不存在', 'data': None}) @@ -761,7 +762,7 @@ class CreateOrderView(APIView): 'ImageURL':shangpin_tupian, 'User1ID':f"Boss{request.user.UserUID}", 'ProductTypeID':shangpin.leixing_id, - 'ClubID': getattr(request, 'club_id', None) or 'xq', + 'ClubID': club_id, } # 创建订单记录 @@ -823,7 +824,8 @@ class CreateOrderView(APIView): jine=shangpin_jiage, beizhu=getattr(settings, 'WEIXIN_PAY_DESCRIPTION', '星阙订单'), user_ip=self.get_client_ip(request), - openid=user_openid + openid=user_openid, + club_id=club_id, ) if not pay_params: @@ -855,16 +857,16 @@ class CreateOrderView(APIView): ip = request.META.get('REMOTE_ADDR') return ip - def generate_wechat_pay_params(self, dingdanid, jine, beizhu, user_ip, openid): + def generate_wechat_pay_params(self, dingdanid, jine, beizhu, user_ip, openid, club_id=None): """ 调用微信支付统一下单接口,生成支付参数 - 完全按照您提供的正确示例代码编写 """ try: - # 微信支付配置 - APPID = getattr(settings, 'WEIXIN_APPID', '') - MCHID = getattr(settings, 'WEIXIN_MCHID', '') - KEY = getattr(settings, 'WEIXIN_SHANGHUMIYAO', '') + from jituan.services.wechat_pay import get_wechat_v2_config + pay_cfg = get_wechat_v2_config(club_id) + APPID = pay_cfg['appid'] + MCHID = pay_cfg['mch_id'] + KEY = pay_cfg['key'] NOTIFY_URL = getattr(settings, 'WEIXIN_NOTIFY_URL', '') if not all([APPID, MCHID, KEY, NOTIFY_URL]): diff --git a/products/views.py b/products/views.py index bf9e7e6..e4cc257 100644 --- a/products/views.py +++ b/products/views.py @@ -61,6 +61,7 @@ from jituan.services.club_config import ( ) from jituan.services.club_context import resolve_club_id_from_request from jituan.services.club_write import resolve_club_id_for_write +from jituan.services.club_user import get_payment_openid from jituan.services.club_penalty import resolve_gsfenhong_club_id import traceback @@ -374,10 +375,14 @@ class YajinGoumai(APIView): # 5. 生成微信支付参数 try: + pay_openid, _ = get_payment_openid(request) + if not pay_openid: + chongzhi_jilu.delete() + return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST) pay_params = self.generate_wechat_pay_params( dingdanid=dingdanid, jine=jine, - openid=request.user.OpenID, # 直接从request.user获取openid + openid=pay_openid, pay_type='yajin' ) except Exception as e: @@ -882,10 +887,14 @@ class JifenBuchong(APIView): # 6. 生成微信支付参数(完整版) try: + pay_openid, _ = get_payment_openid(request) + if not pay_openid: + chongzhi_jilu.delete() + return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST) pay_params = self.generate_wechat_pay_params( dingdanid=dingdanid, jine=jine, - openid=request.user.OpenID, + openid=pay_openid, pay_type='jifen' ) except Exception as e: @@ -1421,10 +1430,14 @@ class HuiyuanGoumai(APIView): # 7. 生成微信支付参数 try: + pay_openid, _ = get_payment_openid(request) + if not pay_openid: + chongzhi_jilu.delete() + return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST) pay_params = self.generate_wechat_pay_params( dingdanid=dingdanid, jine=jine, - openid=request.user.OpenID, + openid=pay_openid, pay_type='huiyuan' ) except Exception as e: @@ -1992,10 +2005,14 @@ class ShangjiaChongzhi(APIView): # 5. 生成微信支付参数 try: + pay_openid, _ = get_payment_openid(request) + if not pay_openid: + chongzhi_jilu.delete() + return Response({'code': 400, 'message': '用户openid不存在'}, status=status.HTTP_400_BAD_REQUEST) pay_params = self.generate_wechat_pay_params( dingdanid=dingdanid, jine=jine, - openid=request.user.OpenID, + openid=pay_openid, pay_type='shangjia' ) except Exception as e: