import hmac import threading import traceback import uuid import hashlib import xmltodict import time import logging import requests import os import secrets import random import string from calendar import monthrange from decimal import Decimal from datetime import date, datetime, timedelta from django.utils import timezone from django.conf import settings from django.core.exceptions import ObjectDoesNotExist from django.core.paginator import Paginator from django.db import models, transaction, IntegrityError from django.db.models import Q, Count, Sum, F, Exists, OuterRef from gvsdsdk.fluent import db, func, FQ from django.db.models.functions import TruncDate, TruncMonth, TruncYear from django.contrib.auth.hashers import make_password from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework.permissions import IsAuthenticated, AllowAny from rest_framework.parsers import JSONParser, MultiPartParser, FormParser # 工具类导入 from utils.oss_utils import validate_image, upload_to_oss, delete_from_oss from backend.utils import ( update_dashou_daily_by_action, update_shangjia_daily ) from jituan.services.club_context import filter_club_char_field, filter_queryset_by_club, filter_user_related_by_club, filter_user_qs_by_club, orders_for_request from jituan.services.catalog_scope import block_non_group_catalog_scope from jituan.services.club_penalty import ( filter_penalty_qs, resolve_penalty_club_id, filter_gsfenhong_qs, forbid_penalty_out_of_scope, resolve_penalty_record_club_id, ) from jituan.services.club_user_access import forbid_if_user_out_of_scope, list_response_meta from shop.utils import update_dianpu_daily_stat from products.utils import update_shangpin_daily_stat from orders.notice_tasks import dingdan_guangbo from ..utils import ( verify_kefu_permission, PERMISSION_TO_SHENFEN, SHENFEN_PROFILE_MAP, has_fadan_view_permission, has_merchant_order_permission, check_fadan_permission, pick_order_id, pick_penalty_create_params, write_xiugai_log, XIUGAI_LEIXING_DASHOU, XIUGAI_LEIXING_GUANSHI, XIUGAI_LEIXING_SHANGJIA, XIUGAI_LEIXING_ZUZHANG, XIUGAI_LEIXING_LABEL, ) # models 集中导入 ## gvsdsdk RBAC 模型(使用 PascalCase 字段名,匹配实际数据库表结构) from gvsdsdk.models import Role, Permission, RolePermission, UserRole ## backend from backend.models import WithdrawalDailyStats ## users from users.models import ( UserGuanshi, UserBoss, UserZuzhang, UserKefu, UserDashou, Xiugaijilu, UserShangjia, UserShenheguan ) from users.business_models import User ## orders from orders.models import ( CommissionRate, PlayerDeliveryImage, PenaltyRecord, OrderPlayerHistory, Order, RefundRecord, MerchantOrderExt, Penalty, PenaltyAppealImage, PenaltyBonus ) ## shop from shop.models import Dianpu, DianpuMorenPeizhi, YonghuPingzheng, ShangpinLeixingDianpu, DianpuShangpinShenheShezhi ## products from products.models import ( Shangpin, ShangpinLeixing, ShangpinZhuanqu, Huiyuan, DuociFenhong, Czjilu, Huiyuangoumai, Gsfenhong ) ## config from config.models import ( WithdrawConfig, ShangjiaLianjie, AccountPermission, TixianQuotaDefault, DailyIncomeStat, DailyPayoutStat, PopupPage, PopupConfig, PopupImage ) ## rank from rank.models import ( KaoheguanBankuai, Bankuai, Chenghao, KaoheCishuFeiyong, YonghuChenghao, ShenheJilu, KaoheJiluFeiyong, KaoheJujueJilu ) # 序列化器 from ..serializers import PopupPageSerializer # 全局常量、日志对象 logger = logging.getLogger('houtai') SHOP_PRODUCT_PERMS = ['1199ab', '1199abc', '1199abd'] class KhgglView(APIView): """ 考核官管理数据接口(列表、筛选、分页) POST /houtai/khggl Body: { "phone": "管理员手机号", "page": 1, // 可选,默认1 "page_size": 15, // 可选,默认15 "yonghuid": "1234567", // 按用户ID筛选,可选 "zhuangtai": 1, // 账号状态 0=禁用,1=正常,可选 "shenhe_zhuangtai": 0, // 审核官状态 0=空闲,1=审核中,可选 "bankuai_name": "王者" // 板块名称模糊筛选,可选 } """ 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) # 分页参数 page = int(request.data.get('page', 1)) page_size = int(request.data.get('page_size', 15)) if page < 1: page = 1 if page_size < 1: page_size = 15 # 筛选条件 filter_yonghuid = request.data.get('yonghuid', '').strip() filter_zhuangtai = request.data.get('zhuangtai') filter_shenhe_zhuangtai = request.data.get('shenhe_zhuangtai') filter_bankuai_name = request.data.get('bankuai_name', '').strip() # 基础查询:所有审核官,预加载用户及打手扩展表 queryset = filter_user_related_by_club( UserShenheguan.query.select_related('user__DashouProfile'), request, ) if filter_yonghuid: queryset = queryset.filter(user__UserUID=filter_yonghuid) if filter_zhuangtai is not None: queryset = queryset.filter(zhuangtai=filter_zhuangtai) if filter_shenhe_zhuangtai is not None: queryset = queryset.filter(shenhe_zhuangtai=filter_shenhe_zhuangtai) # 如果填写了板块名称,筛选出关联该板块的审核官 if filter_bankuai_name: bankuai_ids = Bankuai.query.filter( mingcheng__icontains=filter_bankuai_name ).values_list('bankuai_id', flat=True) shenheguan_ids = KaoheguanBankuai.query.filter( bankuai_id__in=bankuai_ids ).values_list('kaoheguan_id', flat=True) queryset = queryset.filter(user__UserUID__in=shenheguan_ids) total = queryset.count() start = (page - 1) * page_size end = start + page_size shenheguan_list = queryset.order_by('-CreateTime')[start:end] from jituan.services.shenhe_club import yonghu_chenghao_qs_for_request # ---------- 预计算每个板块的打手数量 ---------- bankuai_dashou_count_map = {} all_banquai = Bankuai.query.all() for bk in all_banquai: tag_ids = Chenghao.query.filter(bankuai=bk, leixing='dashou').values_list('id', flat=True) count = yonghu_chenghao_qs_for_request( YonghuChenghao.query.filter( chenghao_id__in=tag_ids, yonghu__DashouProfile__isnull=False, ), request, ).values('yonghu').distinct().count() bankuai_dashou_count_map[bk.bankuai_id] = count # ---------- 新增:板块标签统计 ---------- bankuai_tags_data = [] for bk in all_banquai: tags = Chenghao.query.filter(bankuai=bk, leixing='dashou') tag_list = [] for tag in tags: user_count = yonghu_chenghao_qs_for_request( YonghuChenghao.query.filter(chenghao=tag), request, ).values('yonghu').distinct().count() tag_list.append({ 'id': tag.id, 'name': tag.mingcheng, 'user_count': user_count, }) bankuai_tags_data.append({ 'bankuai_id': bk.bankuai_id, 'mingcheng': bk.mingcheng, 'tags': tag_list, }) # 构造返回数据(审核官列表) data_list = [] for sg in shenheguan_list: user = sg.user # 获取该审核官关联的板块 bk_qs = KaoheguanBankuai.query.filter(kaoheguan_id=user.UserUID).select_related('bankuai') bankuai_info = [] for bk in bk_qs: bid = bk.bankuai.bankuai_id bankuai_info.append({ 'bankuai_id': bid, 'mingcheng': bk.bankuai.mingcheng, 'dashou_count': bankuai_dashou_count_map.get(bid, 0) }) dashou_nick = user.DashouProfile.nicheng if hasattr(user, 'DashouProfile') and user.DashouProfile else '' data_list.append({ 'yonghuid': user.UserUID, 'avatar': user.Avatar or '', 'phone': user.Phone or '', 'zhuangtai': sg.zhuangtai, 'shenhe_zhuangtai': sg.shenhe_zhuangtai, 'shenhe_zongshu': sg.shenhe_zongshu, 'tongguo_zongshu': sg.tongguo_zongshu, 'yue': float(sg.yue), 'zonge': float(sg.zonge), 'CreateTime': sg.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if sg.CreateTime else '', 'UpdateTime': sg.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if sg.UpdateTime else '', 'bankuai': bankuai_info, 'nicheng': dashou_nick, 'is_renzheng': sg.is_renzheng, }) all_bankuai = list(Bankuai.query.values('bankuai_id', 'mingcheng')) return Response({ 'code': 0, 'msg': 'ok', 'data': { 'total': total, 'page': page, 'page_size': page_size, 'list': data_list, 'all_bankuai': all_bankuai, 'bankuai_tags': bankuai_tags_data, # 新增板块标签统计 } }) except Exception as e: logger.exception("KhgglView 接口错误") return Response({'code': 1, 'msg': f'服务器内部错误: {str(e)}'}, status=500) class ShgxgsjView(APIView): """ 审核官信息修改(余额、状态、板块关联) POST /houtai/shgxgsj """ 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 = request.data.get('yonghuid') if not yonghuid: return Response({'code': 1, 'msg': '缺少用户ID'}, status=400) try: shenheguan = UserShenheguan.query.select_related('user').get(user__UserUID=yonghuid) except UserShenheguan.DoesNotExist: return Response({'code': 1, 'msg': '审核官不存在'}, status=404) from jituan.services.shenhe_club import user_belongs_to_request_club if not user_belongs_to_request_club(shenheguan.user, request): return Response({'code': 403, 'msg': '该考核官不属于当前俱乐部'}, status=403) action = request.data.get('action') if action == 'update_info': if 'yue' in request.data: shenheguan.yue = float(request.data.get('yue', 0)) if 'zhuangtai' in request.data: zt = int(request.data.get('zhuangtai')) if zt not in [0, 1]: return Response({'code': 1, 'msg': '无效的账号状态'}, status=400) shenheguan.zhuangtai = zt if 'shenhe_zhuangtai' in request.data: szt = int(request.data.get('shenhe_zhuangtai')) if szt not in [0, 1]: return Response({'code': 1, 'msg': '无效的审核官状态'}, status=400) shenheguan.shenhe_zhuangtai = szt # 新增认证状态编辑 if 'is_renzheng' in request.data: shenheguan.is_renzheng = bool(request.data.get('is_renzheng')) shenheguan.save() return Response({'code': 0, 'msg': '修改成功'}) elif action == 'add_bankuai': bankuai_id = request.data.get('bankuai_id') if not bankuai_id: return Response({'code': 1, 'msg': '缺少板块ID'}, status=400) if not Bankuai.query.filter(bankuai_id=bankuai_id).exists(): return Response({'code': 1, 'msg': '板块不存在'}, status=400) if KaoheguanBankuai.query.filter(kaoheguan_id=yonghuid, bankuai_id=bankuai_id).exists(): return Response({'code': 1, 'msg': '已关联该板块'}, status=400) KaoheguanBankuai.query.create(kaoheguan_id=yonghuid, bankuai_id=bankuai_id) return Response({'code': 0, 'msg': '板块关联成功'}) elif action == 'remove_bankuai': bankuai_id = request.data.get('bankuai_id') if not bankuai_id: return Response({'code': 1, 'msg': '缺少板块ID'}, status=400) deleted, _ = KaoheguanBankuai.query.filter( kaoheguan_id=yonghuid, bankuai_id=bankuai_id ).delete() if not deleted: return Response({'code': 1, 'msg': '未找到该板块关联'}, status=400) return Response({'code': 0, 'msg': '板块移除成功'}) else: return Response({'code': 1, 'msg': '未知操作'}, status=400) except Exception as e: logger.exception("ShgxgsjView 接口错误") return Response({'code': 1, 'msg': f'服务器内部错误: {str(e)}'}, status=500) def _batch_user_profile_map(user_uids): """批量获取用户头像、昵称、手机号""" uids = list({u for u in user_uids if u}) if not uids: return {} users = User.query.filter(UserUID__in=uids) dashou_nicks = { d.user.UserUID: d.nicheng for d in UserDashou.query.filter(user__UserUID__in=uids).select_related('user') } result = {} for u in users: result[u.UserUID] = { 'yonghuid': u.UserUID, 'avatar': u.Avatar or '', 'phone': u.Phone or '', 'nicheng': dashou_nicks.get(u.UserUID) or u.UserName or u.Phone or u.UserUID, } return result def _build_shenhe_jilu_filters(request_data): """构造 ShenheJilu 查询条件(列表与统计共用)""" qs = ShenheJilu.query.select_related('bankuai', 'chenghao') jilu_id = (request_data.get('jilu_id') or '').strip() if jilu_id: qs = qs.filter(jilu_id=jilu_id) zhuangtai = request_data.get('zhuangtai') if zhuangtai is not None and zhuangtai != '': qs = qs.filter(zhuangtai=int(zhuangtai)) assessed = request_data.get('assessed') if assessed == 'done': qs = qs.filter(zhuangtai__in=[1, 2]) elif assessed == 'undone': qs = qs.filter(zhuangtai__in=[0, 3]) bankuai_id = request_data.get('bankuai_id') if bankuai_id not in (None, ''): qs = qs.filter(bankuai_id=int(bankuai_id)) chenghao_id = request_data.get('chenghao_id') if chenghao_id not in (None, ''): qs = qs.filter(chenghao_id=int(chenghao_id)) cishu = request_data.get('cishu') if cishu not in (None, ''): qs = qs.filter(cishu=int(cishu)) dashou_kw = (request_data.get('dashou_keyword') or '').strip() if dashou_kw: dashou_uids = list( User.query.filter( Q(UserUID=dashou_kw) | Q(UserName__icontains=dashou_kw) | Q(Phone__icontains=dashou_kw) | Q(DashouProfile__nicheng__icontains=dashou_kw) ).values_list('UserUID', flat=True) ) if dashou_uids: qs = qs.filter(shenqingren_id__in=dashou_uids) else: qs = qs.none() kg_kw = (request_data.get('kaoheguan_keyword') or '').strip() if kg_kw: kg_uids = list( User.query.filter( Q(UserUID=kg_kw) | Q(UserName__icontains=kg_kw) | Q(Phone__icontains=kg_kw) | Q(DashouProfile__nicheng__icontains=kg_kw) ).values_list('UserUID', flat=True) ) if kg_uids: qs = qs.filter(shenheguan_id__in=kg_uids) else: qs = qs.none() start_time = (request_data.get('start_time') or '').strip() end_time = (request_data.get('end_time') or '').strip() if start_time: qs = qs.filter(CreateTime__gte=start_time) if end_time: qs = qs.filter(CreateTime__lte=end_time) has_kaoheguan = request_data.get('has_kaoheguan') if has_kaoheguan in (True, 'true', '1', 1): qs = qs.exclude(shenheguan_id__isnull=True).exclude(shenheguan_id='') elif has_kaoheguan in (False, 'false', '0', 0): qs = qs.filter(Q(shenheguan_id__isnull=True) | Q(shenheguan_id='')) return qs def _serialize_shenhe_jilu_row(jl, profile_map, fee_map=None, reject_count_map=None): dashou = profile_map.get(jl.shenqingren_id, { 'yonghuid': jl.shenqingren_id, 'avatar': '', 'phone': '', 'nicheng': jl.shenqingren_id, }) kaoheguan = None if jl.shenheguan_id: kaoheguan = profile_map.get(jl.shenheguan_id, { 'yonghuid': jl.shenheguan_id, 'avatar': '', 'phone': '', 'nicheng': jl.shenheguan_id, }) kaoheguan['game_id'] = jl.shenheguan_youxi_id or '' current_fee = 0.0 if fee_map is not None: current_fee = fee_map.get((jl.jilu_id, jl.cishu), 0.0) else: fd = KaoheJiluFeiyong.query.filter(jilu_id=jl.jilu_id, cishu=jl.cishu).first() if fd: current_fee = float(fd.jine) reject_count = 0 if reject_count_map is not None: reject_count = reject_count_map.get(jl.jilu_id, 0) return { 'jilu_id': jl.jilu_id, 'zhuangtai': jl.zhuangtai, 'zhuangtai_text': SHENHE_ZHUANGTAI_MAP.get(jl.zhuangtai, str(jl.zhuangtai)), 'cishu': jl.cishu, 'jiaofei_jine': float(jl.jiaofei_jine or 0), 'current_fee': current_fee, 'bankuai_id': jl.bankuai.bankuai_id if jl.bankuai else None, 'bankuai_name': jl.bankuai.mingcheng if jl.bankuai else '', 'chenghao_id': jl.chenghao.id if jl.chenghao else None, 'chenghao_name': jl.chenghao.mingcheng if jl.chenghao else '', 'chenghao_icon': jl.chenghao.tubiao_url if jl.chenghao else '', 'guize_neirong': jl.guize_neirong or '', 'dashou': { **dashou, 'game_id': jl.dashou_youxi_id or '', 'beizhu': jl.dashou_beizhu or '', }, 'kaoheguan': kaoheguan, 'reject_count': reject_count, 'CreateTime': jl.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if jl.CreateTime else '', 'UpdateTime': jl.UpdateTime.strftime('%Y-%m-%d %H:%M:%S') if jl.UpdateTime else '', } class KhjlglView(APIView): """ 考核记录列表 + 统计 POST /houtai/khjlgl """ 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) page = int(request.data.get('page', 1)) page_size = int(request.data.get('page_size', 20)) if page < 1: page = 1 if page_size < 1: page_size = 20 if page_size > 100: page_size = 100 from jituan.services.shenhe_club import filter_shenhe_jilu_by_request filter_data = request.data qs = filter_shenhe_jilu_by_request( _build_shenhe_jilu_filters(filter_data), request, ) # FluentQuery.filter() 会原地修改同一对象;统计与列表必须各自独立查询 stats_base = filter_shenhe_jilu_by_request( _build_shenhe_jilu_filters(filter_data), request, ) agg = stats_base.aggregate(total_fee=Sum('jiaofei_jine')) tag_rows = filter_shenhe_jilu_by_request( _build_shenhe_jilu_filters(filter_data), request, ).values( 'chenghao_id', 'chenghao__mingcheng' ).annotate( total=Count('jilu_id'), passed=Count('jilu_id', filter=Q(zhuangtai=1)), failed=Count('jilu_id', filter=Q(zhuangtai=2)), in_progress=Count('jilu_id', filter=Q(zhuangtai=0)), pending=Count('jilu_id', filter=Q(zhuangtai=3)), ).order_by('-total') stats = { 'total': stats_base.count(), 'passed': stats_base.filter(zhuangtai=1).count(), 'failed': stats_base.filter(zhuangtai=2).count(), 'in_progress': stats_base.filter(zhuangtai=0).count(), 'pending': stats_base.filter(zhuangtai=3).count(), 'total_fee': float(agg['total_fee'] or 0), 'tag_stats': [ { 'chenghao_id': r['chenghao_id'], 'chenghao_name': r['chenghao__mingcheng'] or '未知标签', 'total': r['total'], 'passed': r['passed'], 'failed': r['failed'], 'in_progress': r['in_progress'], 'pending': r['pending'], } for r in tag_rows if r['chenghao_id'] ], } total = qs.count() start = (page - 1) * page_size rows = qs.order_by('-CreateTime')[start:start + page_size].to_list() uids = [] jilu_ids = [] for jl in rows: uids.append(jl.shenqingren_id) if jl.shenheguan_id: uids.append(jl.shenheguan_id) jilu_ids.append(jl.jilu_id) profile_map = _batch_user_profile_map(uids) fee_pairs = [(jl.jilu_id, jl.cishu) for jl in rows] fee_map = {} if fee_pairs: jids = [p[0] for p in fee_pairs] for fd in KaoheJiluFeiyong.query.filter(jilu_id__in=jids): fee_map[(fd.jilu_id, fd.cishu)] = float(fd.jine) reject_counts = { r['jilu_id']: r['cnt'] for r in KaoheJujueJilu.query.filter(jilu_id__in=jilu_ids) .values('jilu_id') .annotate(cnt=Count('id')) .all() } if jilu_ids else {} data_list = [ _serialize_shenhe_jilu_row(jl, profile_map, fee_map, reject_counts) for jl in rows ] all_bankuai = list(Bankuai.query.values('bankuai_id', 'mingcheng')) all_tags = list( Chenghao.query.filter(leixing='dashou') .values('id', 'mingcheng', 'bankuai_id') .order_by('mingcheng') ) return Response({ 'code': 0, 'msg': 'ok', 'data': { 'total': total, 'page': page, 'page_size': page_size, 'list': data_list, 'stats': stats, 'all_bankuai': all_bankuai, 'all_tags': all_tags, }, }) except Exception as e: logger.exception('KhjlglView 接口错误') return Response({'code': 1, 'msg': f'服务器内部错误: {str(e)}'}, status=500) class KhjlczView(APIView): """ 考核记录操作 / 详情 POST /houtai/khjlcz action: - get_detail: 获取单条详情(含缴费明细、拒绝历史) - to_pending: 考核中 → 待审核(取消指定考核官,与小程序 transfer 一致) """ 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) action = request.data.get('action') jilu_id = (request.data.get('jilu_id') or '').strip() if not jilu_id: return Response({'code': 1, 'msg': '缺少记录ID'}, status=400) if action == 'get_detail': try: jl = ShenheJilu.query.select_related('bankuai', 'chenghao').get(jilu_id=jilu_id) except ShenheJilu.DoesNotExist: return Response({'code': 1, 'msg': '记录不存在'}, status=404) uids = [jl.shenqingren_id] if jl.shenheguan_id: uids.append(jl.shenheguan_id) profile_map = _batch_user_profile_map(uids) fee_list = [ { 'cishu': f.cishu, 'jine': float(f.jine), } for f in KaoheJiluFeiyong.query.filter(jilu_id=jilu_id).order_by('cishu') ] reject_list = [] for r in KaoheJujueJilu.query.filter(jilu_id=jilu_id).order_by('-CreateTime'): kg_prof = _batch_user_profile_map([r.shenheguan_id]).get(r.shenheguan_id, {}) reject_list.append({ 'cishu': r.cishu, 'shenheguan_id': r.shenheguan_id, 'shenheguan_nicheng': kg_prof.get('nicheng', r.shenheguan_id), 'yuanyin': r.yuanyin, 'CreateTime': r.CreateTime.strftime('%Y-%m-%d %H:%M:%S') if r.CreateTime else '', }) record = _serialize_shenhe_jilu_row(jl, profile_map) record['fee_list'] = fee_list record['reject_list'] = reject_list return Response({'code': 0, 'msg': 'ok', 'data': record}) if action == 'to_pending': with transaction.atomic(): jl = ShenheJilu.objects.select_for_update().filter(jilu_id=jilu_id).first() if not jl: return Response({'code': 1, 'msg': '记录不存在'}, status=404) if jl.zhuangtai != 0: return Response({'code': 1, 'msg': '仅「考核中」的记录可退回待审核'}, status=400) old_kg_id = jl.shenheguan_id jl.shenheguan_id = None jl.shenheguan_youxi_id = None jl.zhuangtai = 3 jl.save(update_fields=['shenheguan_id', 'shenheguan_youxi_id', 'zhuangtai', 'UpdateTime']) if old_kg_id: UserShenheguan.query.filter(user__UserUID=old_kg_id).update(shenhe_zhuangtai=0) return Response({'code': 0, 'msg': '已退回待审核,考核官指定已取消'}) return Response({'code': 1, 'msg': '无效的操作类型'}, status=400) except Exception as e: logger.exception('KhjlczView 接口错误') return Response({'code': 1, 'msg': f'服务器内部错误: {str(e)}'}, status=500)