# dengji/views.py
import logging
import json
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from shangpin.models import ShangpinLeixing
from .models import YonghuChenghao, Chenghao, KaoheCishuFeiyong, KaoheJujueJilu
from .utils import get_tag_fee, create_shenhe_jilu

logger = logging.getLogger('dengji')


class DashouBiaoqianView(APIView):
    """获取当前打手所有称号标签"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            # 查询用户的所有称号关联，一次连表取出
            relations = YonghuChenghao.objects.filter(
                yonghu=yonghu
            ).select_related('chenghao')

            chenghao_list = []
            for rel in relations:
                ch = rel.chenghao
                # 解析特效描述 JSON（前端需要对象）
                texiao_json = {}
                if ch.texiao_miaoshu:
                    try:
                        texiao_json = json.loads(ch.texiao_miaoshu)
                    except json.JSONDecodeError:
                        texiao_json = {}
                chenghao_list.append({
                    'mingcheng': ch.mingcheng,
                    'tubiao_url': ch.tubiao_url or '',
                    'texiao_json': texiao_json,
                })

            return Response({
                'code': 0,
                'msg': '成功',
                'data': {'chenghao_list': chenghao_list}
            })
        except Exception as e:
            logger.error(f"获取打手标签失败: {e}", exc_info=True)
            return Response({'code': 1, 'msg': '服务器错误', 'data': None})



from shangpin.models import ShangpinLeixing
from .models import YonghuChenghao, Chenghao
class BankuaiBiaoqianView(APIView):
    """获取商品类型所属板块的所有标签"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        leixing_id = request.data.get('leixing_id')
        if not leixing_id:
            return Response({'code': 1, 'msg': '缺少leixing_id'})

        try:
            leixing = ShangpinLeixing.objects.select_related('bankuai').get(id=leixing_id)
        except ShangpinLeixing.DoesNotExist:
            return Response({'code': 2, 'msg': '商品类型不存在'})

        bankuai = leixing.bankuai
        if not bankuai:
            return Response({'code': 0, 'data': {'biaoqian_list': []}})

        # 获取该板块下所有类型的标签（leixing可以为dashou/shangjia等，这里先返回所有）
        chenghao_list = Chenghao.objects.filter(bankuai=bankuai)
        data = []
        for ch in chenghao_list:
            texiao_json = {}
            if ch.texiao_miaoshu:
                try:
                    texiao_json = json.loads(ch.texiao_miaoshu)
                except:
                    pass
            data.append({
                'id': ch.id,
                'mingcheng': ch.mingcheng,
                'texiao_json': texiao_json
            })
        return Response({'code': 0, 'data': {'biaoqian_list': data}})





# dengji/views.py
import logging
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from .models import KaoheguanBankuai, Bankuai
from django.db import transaction
from yonghu.models import UserShenheguan, UserMain, UserDashou

logger = logging.getLogger('dengji')

# 硬编码邀请码
KAOHEGUAN_INVITE_CODE = 'KHG2026VIP'

class KaoheguanRegisterView(APIView):
    """
    考核官注册接口
    POST /dengji/khgzc
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            invite_code = request.data.get('inviteCode', '').strip()

            if not invite_code:
                return Response({'code': 400, 'msg': '邀请码不能为空'})
            if invite_code != KAOHEGUAN_INVITE_CODE:
                return Response({'code': 400, 'msg': '邀请码错误'})

            kg = UserShenheguan.objects.filter(user=yonghu).first()
            if kg:
                if kg.zhuangtai == 1:
                    return Response({'code': 200, 'msg': '您已是考核官', 'data': self._build_data(kg)})
                else:
                    return Response({'code': 400, 'msg': '账号已被封禁'})

            with transaction.atomic():
                kg = UserShenheguan.objects.create(
                    user=yonghu,
                    zhuangtai=1,
                    shenhe_zhuangtai=0,
                    shenhe_zongshu=0,
                    tongguo_zongshu=0,
                    yue=0.00,
                    zonge=0.00
                )
            return Response({'code': 200, 'msg': '注册成功', 'data': self._build_data(kg)})

        except Exception as e:
            logger.error(f"考核官注册失败: {e}", exc_info=True)
            return Response({'code': 500, 'msg': '服务器内部错误'})

    def _build_data(self, kg):
        bankuai_qs = KaoheguanBankuai.objects.filter(kaoheguan_id=kg.user.yonghuid).select_related('bankuai')
        bankuai_list = [{'bankuai_id': b.bankuai.bankuai_id, 'mingcheng': b.bankuai.mingcheng} for b in bankuai_qs]
        return {
            'zhuangtai': kg.zhuangtai,
            'shenhe_zongshu': kg.shenhe_zongshu,
            'tongguo_zongshu': kg.tongguo_zongshu,
            'yue': str(kg.yue),
            'zonge': str(kg.zonge),
            'shenhe_zhuangtai': kg.shenhe_zhuangtai,
            'bankuai_list': bankuai_list,
            'kaoheguanstatus': 1
        }





class KaoheguanRefreshView(APIView):
    """
    考核官数据刷新接口
    POST /dengji/khgsx
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            kg = UserShenheguan.objects.filter(user=yonghu).first()
            if not kg:
                return Response({'code': 400, 'msg': '您还未注册考核官'})

            if kg.zhuangtai != 1:
                return Response({'code': 200, 'data': {'zhuangtai': kg.zhuangtai, 'kaoheguanstatus': 0}})

            # 查询所属板块
            bankuai_qs = KaoheguanBankuai.objects.filter(kaoheguan_id=kg.user.yonghuid).select_related('bankuai')
            bankuai_list = [{'bankuai_id': b.bankuai.bankuai_id, 'mingcheng': b.bankuai.mingcheng} for b in bankuai_qs]

            # 统计待审核 / 审核中的记录数量
            pending_count = ShenheJilu.objects.filter(
                shenheguan_id=yonghu.yonghuid,
                zhuangtai=0   # 审核中
            ).count()

            data = {
                'zhuangtai': kg.zhuangtai,
                'shenhe_zongshu': kg.shenhe_zongshu,
                'tongguo_zongshu': kg.tongguo_zongshu,
                'yue': str(kg.yue),
                'zonge': str(kg.zonge),
                'shenhe_zhuangtai': kg.shenhe_zhuangtai,
                'bankuai_list': bankuai_list,
                'kaoheguanstatus': 1,
                'is_renzheng': kg.is_renzheng,                 # 🆕 是否认证
                'pending_shenhe_count': pending_count           # 🆕 审核中数量
            }
            return Response({'code': 200, 'data': data})

        except Exception as e:
            logger.error(f"考核官刷新失败: {e}", exc_info=True)
            return Response({'code': 500, 'msg': '服务器内部错误'})


import json
from django.db import transaction, IntegrityError
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from .models import Bankuai, ShenheJilu, KaoheguanBankuai, Chenghao

class ShenheDatingModuleView(APIView):
    """审核大厅获取模块列表（板块 + 待审核数量 + 是否关联）"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            related_ids = set(KaoheguanBankuai.objects.filter(kaoheguan_id=yonghu.yonghuid)
                              .values_list('bankuai_id', flat=True))

            bankuai_list = []
            for bk in Bankuai.objects.all():
                count = ShenheJilu.objects.filter(bankuai=bk, zhuangtai=3, shenheguan_id__isnull=True).count()
                bankuai_list.append({
                    'bankuai_id': bk.bankuai_id,
                    'mingcheng': bk.mingcheng,
                    'count': count,
                    'is_related': bk.bankuai_id in related_ids
                })

            return Response({'code': 0, 'data': {'modules': bankuai_list}})
        except Exception as e:
            return Response({'code': 500, 'msg': str(e)}, status=500)


class ShenheDatingDataView(APIView):
    """获取审核大厅待审核记录列表"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            data = request.data
            bankuai_id = data.get('bankuai_id')
            page = int(data.get('page', 1))
            page_size = int(data.get('page_size', 5))

            query = ShenheJilu.objects.filter(zhuangtai=3, shenheguan_id__isnull=True)
            if bankuai_id:
                query = query.filter(bankuai_id=bankuai_id)

            total = query.count()
            offset = (page - 1) * page_size
            jilu_list = query.select_related('bankuai', 'chenghao').order_by('-create_time')[
                offset:offset + page_size]

            records = []
            for jl in jilu_list:
                user = UserMain.objects.filter(yonghuid=jl.shenqingren_id).first()
                avatar = user.avatar if user else ''
                texiao_json = {}
                if jl.chenghao and jl.chenghao.texiao_miaoshu:
                    try:
                        texiao_json = json.loads(jl.chenghao.texiao_miaoshu)
                    except:
                        pass

                # 新增字段：本次考核费用
                kaohe_feiyong = float(jl.jiaofei_jine) if jl.jiaofei_jine is not None else 0.0

                records.append({
                    'jilu_id': jl.jilu_id,
                    'shenqingren_id': jl.shenqingren_id,
                    'shenqingren_avatar': avatar,
                    'dashou_youxi_id': jl.dashou_youxi_id or '',
                    'dashou_beizhu': jl.dashou_beizhu or '',
                    'bankuai_id': jl.bankuai.bankuai_id if jl.bankuai else None,
                    'bankuai_mingcheng': jl.bankuai.mingcheng if jl.bankuai else '',
                    'chenghao_id': jl.chenghao_id,
                    'chenghao_mingcheng': jl.chenghao.mingcheng if jl.chenghao else '',
                    'chenghao_texiao_json': texiao_json,
                    'guize_neirong': jl.guize_neirong or '',
                    'kaohe_feiyong': kaohe_feiyong,          # 新增
                    'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S') if jl.create_time else '',
                })

            has_more = (page * page_size) < total
            return Response({'code': 0, 'data': {'list': records, 'has_more': has_more, 'total': total}})
        except Exception as e:
            return Response({'code': 500, 'msg': str(e)}, status=500)

class ShenheQiangdanView(APIView):
    """
    审核官抢单（接审核任务）
    校验：身份、账号封禁、已有进行中审核、记录状态、不能审核自己、板块权限
    成功后更新考核官扩展表：审核总数+1，审核状态设为“审核中”
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            jilu_id = request.data.get('jilu_id')
            if not jilu_id:
                return Response({'code': 400, 'msg': '记录ID不能为空'})

            # 1. 检查考核官身份及账号是否被禁用
            kg = UserShenheguan.objects.filter(user=yonghu, zhuangtai=1).first()
            if not kg:
                return Response({'code': 403, 'msg': '您不是考核官或账号已被禁用'})

            # 2. 检查是否有正在审核中的记录（zhuangtai=0），防止同时审核多个
            ongoing = ShenheJilu.objects.filter(
                shenheguan_id=yonghu.yonghuid, zhuangtai=0
            ).exists()
            if ongoing:
                return Response({'code': 400, 'msg': '您有正在审核中的任务，请完成后再接新任务'})

            with transaction.atomic():
                # 3. 行锁抢单：仅当状态为待审核(3)且无审核官时才能抢
                jilu = ShenheJilu.objects.select_for_update().filter(
                    jilu_id=jilu_id,
                    zhuangtai=3,
                    shenheguan_id__isnull=True
                ).first()
                if not jilu:
                    return Response({'code': 400, 'msg': '该审核任务已被接走、状态变更或不存在'})

                # 4. 不能审核自己
                if jilu.shenqingren_id == yonghu.yonghuid:
                    return Response({'code': 400, 'msg': '不能审核自己提交的申请'})

                # 5. 板块权限：考核官必须属于该板块
                is_related = KaoheguanBankuai.objects.filter(
                    kaoheguan_id=yonghu.yonghuid,
                    bankuai=jilu.bankuai
                ).exists()
                if not is_related:
                    return Response({'code': 400, 'msg': '您不属于该板块，无法审核'})

                # 新增：6. 费用>0时，要求考核官已认证
                if jilu.jiaofei_jine and float(jilu.jiaofei_jine) > 0:
                    if not kg.is_renzheng:
                        return Response({'code': 400, 'msg': '本考核需要认证考核官接单，您尚未认证'})

                # 7. 更新审核记录：分配给当前考核官，状态变为审核中
                jilu.zhuangtai = 0  # 审核中
                jilu.shenheguan_id = yonghu.yonghuid
                jilu.save()

                # 8. 更新考核官扩展表：审核总数 +1，审核状态置为审核中（1）
                UserShenheguan.objects.filter(user=yonghu).update(
                    shenhe_zongshu=F('shenhe_zongshu') + 1,
                    shenhe_zhuangtai=1
                )

            return Response({
                'code': 0,
                'msg': '抢单成功，请前往游戏内审核，审核完成后请到考核打分页面进行评定。',
                'data': {'bankuai_id': jilu.bankuai.bankuai_id}
            })

        except Exception as e:
            logger.error(f"审核官抢单异常: {str(e)}", exc_info=True)
            return Response({'code': 500, 'msg': '服务器内部错误'}, status=500)






import json
import logging
from decimal import Decimal

from django.db import transaction, models
from django.db.models import F, Q, OuterRef, Subquery, Count, Max
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

class ShenheXiangqingView(APIView):
    """获取当前考核官审核中的记录详情（新增待收考核费字段）"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            kg = UserShenheguan.objects.filter(user=yonghu, zhuangtai=1).first()
            if not kg:
                return Response({'code': 403, 'msg': '您不是考核官或账号异常'})

            page = int(request.data.get('page', 1))
            page_size = int(request.data.get('page_size', 10))

            # 查询当前考核官名下状态为“审核中”的记录
            base_query = ShenheJilu.objects.filter(
                shenheguan_id=yonghu.yonghuid,
                zhuangtai=0
            ).select_related('bankuai', 'chenghao')
            total = base_query.count()
            offset = (page - 1) * page_size
            jilu_list = base_query[offset:offset + page_size]

            records = []
            for jl in jilu_list:
                user = UserMain.objects.filter(yonghuid=jl.shenqingren_id).first()
                avatar = user.avatar if user else ''
                texiao_json = {}
                if jl.chenghao and jl.chenghao.texiao_miaoshu:
                    try:
                        texiao_json = json.loads(jl.chenghao.texiao_miaoshu)
                    except:
                        pass

                # 是否开启金牌
                is_jinpai = jl.chenghao.kaioi_jinpai if jl.chenghao else False

                # 本次待收考核费（基于记录中的当前次数，从费用明细表查询）
                daishou_fei = 0.00
                fee_detail = KaoheJiluFeiyong.objects.filter(
                    jilu=jl,
                    cishu=jl.cishu
                ).first()
                if fee_detail:
                    daishou_fei = float(fee_detail.jine)
                else:
                    # 兜底：若明细表无记录，尝试用通用费用表计算
                    daishou_fei = 0.00

                # 上次失败原因
                last_fail_reason = ''
                last_fail = KaoheJujueJilu.objects.filter(
                    jilu=jl,
                    cishu=jl.cishu - 1
                ).order_by('-create_time').first()
                if last_fail:
                    last_fail_reason = last_fail.yuanyin

                records.append({
                    'jilu_id': jl.jilu_id,
                    'shenqingren_id': jl.shenqingren_id,
                    'shenqingren_avatar': avatar,
                    'bankuai_mingcheng': jl.bankuai.mingcheng if jl.bankuai else '',
                    'chenghao_mingcheng': jl.chenghao.mingcheng if jl.chenghao else '',
                    'chenghao_texiao_json': texiao_json,
                    'guize_neirong': jl.guize_neirong or '',
                    'dashou_beizhu': jl.dashou_beizhu or '',
                    'dashou_youxi_id': jl.dashou_youxi_id or '',
                    'shenheguan_youxi_id': jl.shenheguan_youxi_id or '',
                    'cishu': jl.cishu,
                    'daishou_fei': daishou_fei,           # 新增：待收考核费
                    'last_fail_reason': last_fail_reason,
                    'is_jinpai': is_jinpai,
                    'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S') if jl.create_time else '',
                })

            has_more = (page * page_size) < total
            return Response({'code': 0, 'data': {'list': records, 'has_more': has_more, 'total': total}})
        except Exception as e:
            return Response({'code': 500, 'msg': str(e)}, status=500)

class ShenheCaozuoView(APIView):
    """
    考核官执行操作（同意/拒绝/转移/修改昵称），并更新考核官收益
    - 只有“同意”或“拒绝”才增加余额和总额，金额严格从 KaoheJiluFeiyong 表获取
    - 查不到费用则加 0 元，绝不影响流程
    - 转移、修改昵称等操作不涉及收益
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            # 1. 验证考核官身份及账号状态
            kg = UserShenheguan.objects.filter(user=yonghu, zhuangtai=1).first()
            if not kg:
                return Response({'code': 403, 'msg': '账号异常，无法操作'})

            jilu_id = request.data.get('jilu_id')
            caozuo = request.data.get('caozuo')      # agree / reject / transfer / modify_nick
            if not jilu_id or not caozuo:
                return Response({'code': 400, 'msg': '缺少必要参数'})

            with transaction.atomic():
                # 2. 锁定审核记录，确保属于当前考核官且状态为审核中(0)
                jilu = ShenheJilu.objects.select_for_update().filter(
                    jilu_id=jilu_id,
                    shenheguan_id=yonghu.yonghuid,
                    zhuangtai=0
                ).first()
                if not jilu:
                    return Response({'code': 400, 'msg': '该记录不存在或不属于您'})

                # 3. 本次操作产生的收入（仅通过/拒绝时有意义）
                daishou_fei = 0.00

                # 4. 根据操作类型执行对应业务逻辑
                if caozuo == 'agree':
                    # --- 通过考核 ---
                    # 查询本次考核应得的费用（基于记录ID和当前次数）
                    fee_detail = KaoheJiluFeiyong.objects.filter(
                        jilu=jilu,
                        cishu=jilu.cishu
                    ).first()
                    if fee_detail:
                        daishou_fei = float(fee_detail.jine)
                    # 找不到就保持 0，绝不使用任何默认值

                    jilu.zhuangtai = 1
                    jilu.save()

                    # 授予标签
                    if jilu.chenghao:
                        yh = UserMain.objects.get(yonghuid=jilu.shenqingren_id)
                        if not YonghuChenghao.objects.filter(yonghu=yh, chenghao=jilu.chenghao).exists():
                            YonghuChenghao.objects.create(yonghu=yh, chenghao=jilu.chenghao)
                        # 如果标签开启了金牌，同步更新打手称号
                        if jilu.chenghao.kaioi_jinpai:
                            dashou_prof = UserDashou.objects.filter(user=yh).first()
                            if dashou_prof:
                                dashou_prof.chenghao = '金牌选手'
                                dashou_prof.save()

                elif caozuo == 'reject':
                    # --- 拒绝考核 ---
                    yuanyin = request.data.get('yuanyin', '')
                    if not yuanyin.strip():
                        return Response({'code': 400, 'msg': '请填写拒绝原因'})

                    # 查询本次考核应得的费用（拒绝时同样获得收入）
                    fee_detail = KaoheJiluFeiyong.objects.filter(
                        jilu=jilu,
                        cishu=jilu.cishu
                    ).first()
                    if fee_detail:
                        daishou_fei = float(fee_detail.jine)
                    # 找不到就保持 0

                    jilu.zhuangtai = 2
                    jilu.save()
                    # 记录拒绝原因
                    KaoheJujueJilu.objects.create(
                        jilu=jilu,
                        cishu=jilu.cishu,
                        shenheguan_id=yonghu.yonghuid,
                        yuanyin=yuanyin
                    )

                    # 新增：不合格时，如果考核官未认证，则清空考核官ID和游戏昵称
                    if not kg.is_renzheng:
                        jilu.shenheguan_id = None
                        jilu.shenheguan_youxi_id = ''
                        jilu.save(update_fields=['shenheguan_id', 'shenheguan_youxi_id'])

                elif caozuo == 'transfer':
                    # 转移考核官：清空考核官信息，状态回退为待审核
                    jilu.shenheguan_id = None
                    jilu.shenheguan_youxi_id = None
                    jilu.zhuangtai = 3
                    jilu.save()
                    # 转移不更新收益，直接返回


                elif caozuo == 'modify_nick':
                    # 修改考核官游戏昵称
                    youxi_id = request.data.get('youxi_id', '').strip()
                    if not youxi_id:
                        return Response({'code': 400, 'msg': '请输入游戏昵称'})
                    jilu.shenheguan_youxi_id = youxi_id
                    jilu.save()
                    return Response({'code': 0, 'msg': '修改成功'})

                else:
                    return Response({'code': 400, 'msg': '无效的操作类型'})

                # 5. 更新考核官收益（仅“通过”或“拒绝”时执行）
                if caozuo in ('transfer'):
                    update_fields = {

                        'shenhe_zhuangtai': 0,  # 设为空闲
                    }
                    UserShenheguan.objects.filter(user=yonghu).update(**update_fields)
                if caozuo in ('agree', 'reject'):
                    update_fields = {
                        'yue': F('yue') + Decimal(str(daishou_fei)),
                        'zonge': F('zonge') + Decimal(str(daishou_fei)),
                        'shenhe_zhuangtai': 0,   # 设为空闲
                    }
                    # 只有同意时才增加“通过总数”
                    if caozuo == 'agree':
                        update_fields['tongguo_zongshu'] = F('tongguo_zongshu') + 1

                    # 审核总数不再增加
                    UserShenheguan.objects.filter(user=yonghu).update(**update_fields)

                return Response({'code': 0, 'msg': '操作成功'})

        except Exception as e:
            logger.error(f"考核操作异常: {str(e)}", exc_info=True)
            return Response({'code': 500, 'msg': '服务器内部错误'}, status=500)





# dengji/views.py
class KaoheJinpaiTagsView(APIView):
    """获取考核金牌页面的标签和板块信息"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            user = request.user
            # 获取用户已拥有的标签名称集合
            owned_names = set(
                YonghuChenghao.objects.filter(yonghu=user, chenghao__leixing='dashou')
                .values_list('chenghao__mingcheng', flat=True)
            )

            # 板块列表
            plate_list = []
            for bk in Bankuai.objects.all():
                tags = Chenghao.objects.filter(bankuai=bk, leixing='dashou')
                tag_list = []
                for tag in tags:
                    # 费用列表
                    fee_objs = KaoheCishuFeiyong.objects.filter(chenghao=tag).order_by('cishu')
                    fee_list = [{'cishu': f.cishu, 'feiyong': float(f.feiyong)} for f in fee_objs]

                    # 若没有记录，补充默认费用
                    if not fee_list:
                        fee_list = [{'cishu': 1, 'feiyong': 5.00}]

                    tag_list.append({
                        'id': tag.id,
                        'name': tag.mingcheng,
                        'texiao_json': json.loads(tag.texiao_miaoshu) if tag.texiao_miaoshu else {},
                        'jinpai': tag.kaioi_jinpai,
                        'rule': tag.kaohe_guize or '',
                        'fee_list': fee_list,
                        'owned': tag.mingcheng in owned_names,
                    })

                if tag_list:
                    plate_list.append({
                        'bankuai_id': bk.bankuai_id,
                        'mingcheng': bk.mingcheng,
                        'tags': tag_list
                    })

            # 新增：返回所有在职考核官信息（用于指定考核官）
            kaoheguan_list = []
            for kg in UserShenheguan.objects.filter(zhuangtai=1).select_related('user'):
                uid = kg.user.yonghuid
                avatar = kg.user.avatar or ''
                # 获取考核官的打手昵称（从打手扩展表）
                dashou_nick = ''
                dashou_prof = UserDashou.objects.filter(user=kg.user).first()
                if dashou_prof:
                    dashou_nick = dashou_prof.nicheng or ''
                kaoheguan_list.append({
                    'yonghuid': uid,
                    'avatar': avatar,
                    'dashou_nick': dashou_nick,
                    'is_renzheng': kg.is_renzheng,
                    'shenhe_zhuangtai': kg.shenhe_zhuangtai,
                })

            return Response({
                'code': 0,
                'data': {
                    'plate_list': plate_list,
                    'my_tags': list(owned_names),
                    'kaoheguan_list': kaoheguan_list,   # 新增
                }
            })
        except Exception as e:
            return Response({'code': 500, 'msg': str(e)}, status=500)

# dengji/utils.py
from .models import Chenghao, KaoheCishuFeiyong, ShenheJilu, KaoheJiluFeiyong, YonghuChenghao
from yonghu.models import UserMain
from django.db import models
class KaoheJiluView(APIView):
    """获取打手本人的考核记录（支持筛选状态）"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            user = request.user
            status = request.data.get('status', 'pending')  # pending / passed
            page = int(request.data.get('page', 1))
            page_size = int(request.data.get('page_size', 5))

            if status == 'pending':
                # 进行中/未通过：审核中(0)、待审核(3)、未通过(2)
                query = ShenheJilu.objects.filter(
                    shenqingren_id=user.yonghuid,
                    zhuangtai__in=[0, 2, 3]
                )
            else:
                query = ShenheJilu.objects.filter(
                    shenqingren_id=user.yonghuid,
                    zhuangtai=1  # 已通过
                )

            total = query.count()
            records = query.order_by('-create_time')[(page-1)*page_size : page*page_size]

            data = []
            for jl in records:
                # 汇总缴纳总额
                total_fee = KaoheJiluFeiyong.objects.filter(jilu=jl).aggregate(
                    total=models.Sum('jine')
                )['total'] or 0.00

                # 上次拒绝原因（最近一条）
                last_fail = KaoheJujueJilu.objects.filter(jilu=jl).order_by('-create_time').first()
                fail_reason = last_fail.yuanyin if last_fail else ''

                # 考核官头像
                kg_user = UserMain.objects.filter(yonghuid=jl.shenheguan_id).first()
                kg_avatar = kg_user.avatar if kg_user else ''

                data.append({
                    'jilu_id': jl.jilu_id,
                    'chenghao_name': jl.chenghao.mingcheng if jl.chenghao else '',
                    'bankuai_name': jl.bankuai.mingcheng if jl.bankuai else '',
                    'zhuangtai': jl.zhuangtai,
                    'statusText': dict(ShenheJilu._meta.get_field('zhuangtai').choices).get(jl.zhuangtai, '未知'),
                    'statusColor': {0: '#FFA500', 1: '#27ae60', 2: '#e74c3c', 3: '#3498db'}.get(jl.zhuangtai, '#888'),
                    'shenheguan_id': jl.shenheguan_id,
                    'shenheguan_avatar': kg_avatar,
                    'dashou_youxi_id': jl.dashou_youxi_id,
                    'dashou_beizhu': jl.dashou_beizhu,
                    'cishu': jl.cishu,
                    'total_fee': float(total_fee),
                    'last_fail_reason': fail_reason,
                    'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S'),
                    # 为再次申请预留标签对象数据（前端可能用到）
                    'tag_obj': {
                        'id': jl.chenghao_id,
                        'name': jl.chenghao.mingcheng if jl.chenghao else '',
                        # 其他字段按需，但申请时会重新拉取
                    } if jl.chenghao else None,
                })

            has_more = (page * page_size) < total
            return Response({
                'code': 0,
                'data': {'list': data, 'has_more': has_more, 'total': total}
            })
        except Exception as e:
            return Response({'code': 500, 'msg': str(e)}, status=500)


from .utils import validate_shenheguan
class KaoheFreeApplyView(APIView):
    """免费申请考核（首次/再次，费用为0时调用）"""
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            user = request.user
            tag_id = request.data.get('tag_id')
            game_nick = request.data.get('game_nick', '').strip()
            remark = request.data.get('remark', '').strip()
            reapply = request.data.get('reapply', False)
            jilu_id = request.data.get('jilu_id') if reapply else None
            shenheguan_id = request.data.get('shenheguan_id', '').strip()  # 新增

            if not tag_id or not game_nick:
                return Response({'code': 400, 'msg': '标签ID和游戏昵称必填'})

            # 校验费用是否为0
            try:
                chenghao = Chenghao.objects.get(id=tag_id)
            except Chenghao.DoesNotExist:
                return Response({'code': 400, 'msg': '标签不存在'})

            # 计算本次次数
            if reapply and jilu_id:
                last_record = ShenheJilu.objects.filter(
                    jilu_id=jilu_id, shenqingren_id=user.yonghuid, zhuangtai=2
                ).first()
                if not last_record:
                    return Response({'code': 400, 'msg': '原记录不存在或状态不是未通过'})
                new_cishu = last_record.cishu + 1
            else:
                max_cishu = ShenheJilu.objects.filter(
                    shenqingren_id=user.yonghuid, chenghao=chenghao, zhuangtai__in=[1,2]
                ).aggregate(max=models.Max('cishu'))['max'] or 0
                new_cishu = max_cishu + 1

            fee = get_tag_fee(chenghao, new_cishu)
            if fee > 0:
                return Response({'code': 400, 'msg': '您有未通过的记录请查看并重考'})

            # 新增：如果指定了考核官，进行合法性校验
            if shenheguan_id:
                valid, err = validate_shenheguan(shenheguan_id, chenghao.bankuai, fee, user)
                if not valid:
                    return Response({'code': 400, 'msg': err})

            # 调用公共创建逻辑
            success, msg, record = create_shenhe_jilu(
                user, tag_id, game_nick, remark, reapply, jilu_id,
                shenheguan_id=shenheguan_id   # 新增参数
            )
            if success:
                return Response({'code': 0, 'msg': msg, 'data': {'jilu_id': record.jilu_id}})
            else:
                return Response({'code': 400, 'msg': msg})
        except Exception as e:
            return Response({'code': 500, 'msg': str(e)}, status=500)




class KaoheJiluListView(APIView):
    """
    获取当前考核官的历史审核记录
    路径：POST /dengji/khghqkhjl
    权限：JWT Token (考核官)
    参数：
        bankuai_id : int (可选，0或空表示全部)
        status    : int (可选，0-全部 1-审核中 2-已通过 3-未通过)
        page      : int (默认1)
        page_size : int (默认5)
    返回：
        list, has_more, total
    """
    permission_classes = [IsAuthenticated]

    def post(self, request):
        try:
            yonghu = request.user
            # 1. 验证考核官身份及账号状态
            kg = UserShenheguan.objects.filter(user=yonghu, zhuangtai=1).first()
            if not kg:
                return Response({'code': 403, 'msg': '您不是考核官或账号异常'})

            # 2. 获取参数
            bankuai_id = request.data.get('bankuai_id')
            status = int(request.data.get('status', 0))   # 0全部 1审核中 2已通过 3未通过
            page = int(request.data.get('page', 1))
            page_size = int(request.data.get('page_size', 5))

            # 3. 构建查询条件：只查当前考核官审核的记录
            base_query = ShenheJilu.objects.filter(shenheguan_id=yonghu.yonghuid)

            # 板块筛选
            if bankuai_id and int(bankuai_id) > 0:
                base_query = base_query.filter(bankuai_id=int(bankuai_id))

            # 状态筛选（前端传的状态映射到后端zhuangtai字段）
            status_map = {
                0: None,          # 全部不筛选
                1: 0,             # 审核中
                2: 1,             # 已通过
                3: 2,             # 未通过
            }
            if status_map.get(status) is not None:
                base_query = base_query.filter(zhuangtai=status_map[status])

            # 4. 计数与分页
            total = base_query.count()
            offset = (page - 1) * page_size
            jilu_list = base_query.order_by('-create_time')[offset:offset + page_size]

            # 5. 预取关联数据，减少查询次数
            jilu_list = jilu_list.select_related('bankuai', 'chenghao')
            # 为每条记录预取费用明细和拒绝记录（通过 related_name 或手动过滤）
            # 由于 KaoheJiluFeiyong 和 KaoheJujueJilu 通过外键指向 ShenheJilu (to_field='jilu_id')，
            # 可以使用 prefetch_related
            jilu_ids = [j.jilu_id for j in jilu_list]
            fee_dict = {}
            reject_dict = {}
            if jilu_ids:
                # 批量获取所有费用明细
                fee_qs = KaoheJiluFeiyong.objects.filter(jilu_id__in=jilu_ids).order_by('cishu')
                for fee in fee_qs:
                    if fee.jilu_id not in fee_dict:
                        fee_dict[fee.jilu_id] = []
                    fee_dict[fee.jilu_id].append({'cishu': fee.cishu, 'jine': float(fee.jine)})

                # 批量获取所有拒绝记录
                reject_qs = KaoheJujueJilu.objects.filter(jilu_id__in=jilu_ids).order_by('cishu')
                for rej in reject_qs:
                    if rej.jilu_id not in reject_dict:
                        reject_dict[rej.jilu_id] = []
                    reject_dict[rej.jilu_id].append({
                        'cishu': rej.cishu,
                        'yuanyin': rej.yuanyin,
                        'create_time': rej.create_time.strftime('%Y-%m-%d %H:%M:%S') if rej.create_time else ''
                    })

            # 6. 批量获取申请人信息（昵称和头像）
            applicant_ids = {j.shenqingren_id for j in jilu_list}
            user_map = {}
            if applicant_ids:
                users = UserMain.objects.filter(yonghuid__in=applicant_ids).select_related('dashou_profile')
                for u in users:
                    avatar = u.avatar or ''
                    nicheng = ''
                    try:
                        # 打手扩展表可能有 nicheng
                        nicheng = u.dashou_profile.nicheng if u.dashou_profile else ''
                    except UserDashou.DoesNotExist:
                        pass
                    user_map[u.yonghuid] = {
                        'avatar': avatar,
                        'nicheng': nicheng or f'用户{u.yonghuid}'
                    }

            # 7. 组装数据
            records = []
            for jl in jilu_list:
                user_info = user_map.get(jl.shenqingren_id, {'avatar': '', 'nicheng': '未知'})
                # 标签特效JSON
                texiao_json = {}
                if jl.chenghao and jl.chenghao.texiao_miaoshu:
                    try:
                        texiao_json = json.loads(jl.chenghao.texiao_miaoshu)
                    except:
                        pass

                # 汇总总缴纳费用
                fee_items = fee_dict.get(jl.jilu_id, [])
                total_fee = sum(item['jine'] for item in fee_items)

                records.append({
                    'jilu_id': jl.jilu_id,
                    'shenqingren_id': jl.shenqingren_id,
                    'shenqingren_avatar': user_info['avatar'],
                    'shenqingren_nicheng': user_info['nicheng'],
                    'bankuai_mingcheng': jl.bankuai.mingcheng if jl.bankuai else '',
                    'chenghao_mingcheng': jl.chenghao.mingcheng if jl.chenghao else '',
                    'chenghao_texiao_json': texiao_json,
                    'zhuangtai': jl.zhuangtai,   # 0审核中 1通过 2未通过 3待审核
                    'cishu': jl.cishu,
                    'total_fee': total_fee,
                    'dashou_youxi_id': jl.dashou_youxi_id or '',
                    'dashou_beizhu': jl.dashou_beizhu or '',
                    'shenheguan_youxi_id': jl.shenheguan_youxi_id or '',
                    'guize_neirong': jl.guize_neirong or '',
                    'create_time': jl.create_time.strftime('%Y-%m-%d %H:%M:%S') if jl.create_time else '',
                    'update_time': jl.update_time.strftime('%Y-%m-%d %H:%M:%S') if jl.update_time else '',
                    'fee_list': fee_items,
                    'reject_list': reject_dict.get(jl.jilu_id, []),
                })

            has_more = (page * page_size) < total
            return Response({
                'code': 0,
                'data': {
                    'list': records,
                    'has_more': has_more,
                    'total': total
                }
            })

        except Exception as e:
            logger.error(f"获取考核记录异常: {str(e)}", exc_info=True)
            return Response({'code': 500, 'msg': '服务器内部错误'}, status=500)