"""考核官后台管理(按俱乐部隔离)。""" import logging from django.db import transaction from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView from backend.view import verify_kefu_permission from jituan.services.club_user import get_user_club_id from jituan.services.shenhe_club import user_belongs_to_request_club from rank.models import Bankuai, KaoheguanBankuai from users.business_models import User from users.models import UserShenheguan logger = logging.getLogger(__name__) def _normalize_bankuai_ids(data): """将板块 ID 统一为整数(bankuai_id 为 AutoField)。""" ids = data.get('bankuai_ids') if ids is None and data.get('bankuai_id') is not None: ids = [data.get('bankuai_id')] if not isinstance(ids, list): return [] out = [] for item in ids: try: bid = int(str(item).strip()) except (TypeError, ValueError): continue if bid > 0 and bid not in out: out.append(bid) return out class ClubKhgglAddView(APIView): """ 后台添加考核官(升级为考核官并关联板块)。 POST /jituan/houtai/khggl-add Body: { "phone": "管理员手机号", "yonghuid": "用户ID", "bankuai_ids": ["bk001", "bk002"], // 或 bankuai_id 单个 "is_renzheng": true // 可选,默认 true } """ permission_classes = [IsAuthenticated] def post(self, request): try: username_from_frontend = request.data.get('phone', None) kefu_obj, permissions = verify_kefu_permission(request, username_from_frontend) if kefu_obj is None: return permissions if 'kaohepeizhi' not in permissions: return Response({'code': 403, 'msg': '无考核管理权限'}, status=403) yonghuid = str(request.data.get('yonghuid', '')).strip() bankuai_ids = _normalize_bankuai_ids(request.data) is_renzheng = request.data.get('is_renzheng', True) if isinstance(is_renzheng, str): is_renzheng = is_renzheng.lower() in ('1', 'true', 'yes') if not yonghuid: return Response({'code': 1, 'msg': '请输入用户ID'}, status=400) if not bankuai_ids: return Response({'code': 1, 'msg': '请选择至少一个板块'}, status=400) try: user = User.query.get(UserUID=yonghuid) except User.DoesNotExist: return Response({'code': 1, 'msg': '用户ID不存在'}, status=404) if not user_belongs_to_request_club(user, request): return Response({'code': 403, 'msg': '该用户不属于当前俱乐部,无法添加为考核官'}, status=403) # 一次性查询所有板块是否存在,避免循环内 N+1 exists _existing_bids = set( Bankuai.query.filter(bankuai_id__in=bankuai_ids) .values_list('bankuai_id', flat=True) ) for bid in bankuai_ids: if bid not in _existing_bids: return Response({'code': 1, 'msg': f'板块不存在: {bid}'}, status=400) created_new = False with transaction.atomic(): kg, created_new = UserShenheguan.query.get_or_create( user=user, defaults={ 'zhuangtai': 1, 'shenhe_zhuangtai': 0, 'is_renzheng': bool(is_renzheng), 'shenhe_zongshu': 0, 'tongguo_zongshu': 0, 'yue': 0, 'zonge': 0, }, ) if not created_new: if kg.zhuangtai != 1: kg.zhuangtai = 1 if is_renzheng: kg.is_renzheng = True kg.save() added_bankuai = [] for bid in bankuai_ids: rel, rel_created = KaoheguanBankuai.query.get_or_create( kaoheguan_id=yonghuid, bankuai_id=bid, ) if rel_created: added_bankuai.append(bid) msg = '考核官添加成功' if created_new else '已关联板块(该用户已是考核官)' return Response({ 'code': 0, 'msg': msg, 'data': { 'yonghuid': yonghuid, 'created': created_new, 'added_bankuai_ids': added_bankuai, 'club_id': get_user_club_id(user), 'is_renzheng': bool(kg.is_renzheng), }, }) except Exception as e: logger.exception('ClubKhgglAddView 接口错误') return Response({'code': 1, 'msg': f'服务器内部错误: {str(e)}'}, status=500)