Files
Django/jituan/views_shenhe_manage.py
XingQue 118260a710 fix: 修复考核官添加板块校验与板块改名接口
板块 ID 统一按整数校验,避免字符串与数据库整型比较导致误报不存在;板块接口补充 scope 与 bankuai_id 校验。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-16 15:33:54 +08:00

132 lines
5.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""考核官后台管理(按俱乐部隔离)。"""
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)