

from rest_framework.views import APIView
from rest_framework.exceptions import ParseError
from rest_framework.permissions import IsAdminUser, AllowAny
from rest_framework.response import Response
from rest_framework.serializers import Serializer
from rest_framework.decorators import action
from apps.am.models import Area
from apps.am.tasks import cache_areas_info
from apps.develop.serializers import AreaManSerializer, CleanDataSerializer, GenerateVoiceSerializer, SendSmsSerializer, SpeakerSerializer, \
    TestTaskSerializer, TestAlgoSerializer, ServerTimeSerializer
from apps.develop.tasks import backup_database, backup_media, reload_web_git, reload_server_git, reload_server_only
from rest_framework.exceptions import APIException
from apps.ecm.service import check_not_in_place, create_remind, handle_xx_event, loc_change, notify_event, rail_in, snap_and_analyse
from apps.ecm.tasks import opl_task, update_count_people
from apps.hrm.models import Employee
from apps.opm.models import Opl
from apps.third.dahua import dhClient
from apps.third.speaker import spClient
from apps.third.models import TDevice
from apps.utils.sms import send_sms
from apps.utils.speech import generate_voice
from apps.utils.tools import get_info_from_id
import importlib
from rest_framework_simplejwt.authentication import JWTAuthentication
from rest_framework.authentication import BasicAuthentication, SessionAuthentication

from apps.utils.viewsets import CustomGenericViewSet
from apps.utils.wx import wxClient
from apps.wf.models import Transition
from django.db import transaction
from django.core.cache import cache
from apps.utils.decorators import auto_log
from django.http import HttpResponse
from server.settings import SD_PWD, TIME_ZONE
import subprocess
from drf_yasg.utils import swagger_auto_schema
from datetime import datetime
# Create your views here.

class ServerTime(APIView):

    def get_permissions(self):
        if self.request.method == 'GET':
            return [AllowAny()]
        return [IsAdminUser()]

    @swagger_auto_schema(responses={200: ServerTimeSerializer})
    def get(self, request):
        """
        获取服务器时间

        获取服务器时间
        """
        return Response({"server_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "timezone": TIME_ZONE})

    @swagger_auto_schema(request_body=ServerTimeSerializer)
    def post(self, request):
        """
        修改服务器时间

        修改服务器时间
        """
        command = f'date -s "{request.data["server_time"]}"'
        completed = subprocess.run(
            ["sudo", "-S", "sh", "-c", command],  # 添加 -S 参数
            input=SD_PWD + "\n",  # 注意要在密码后加换行符
            capture_output=True,
            text=True
        )
        if completed.returncode != 0:
            raise ParseError(completed.stderr)
        return Response()

class ReloadServerGit(APIView):
    permission_classes = [IsAdminUser]

    def post(self, request):
        """
        拉取后端代码并重启服务

        拉取后端代码并重启服务
        """
        reload_server_git.delay()
        return Response()
        # if completed.returncode == 0:
        #     return Response()
        # else:
        #     from server.settings import myLogger
        #     myLogger.error(completed)
        #     raise ParseError(completed.stderr)


class ReloadClientGit(APIView):
    permission_classes = [IsAdminUser]

    def post(self, request):
        """
        拉取前端代码并打包

        拉取前端代码并打包
        """
        reload_web_git.delay()
        return Response()
        # completed = reload_web_git()
        # if completed.returncode == 0:
        #     return Response()
        # else:
        #     raise APIException(completed.stdout)


class ReloadServerOnly(APIView):
    permission_classes = [IsAdminUser]

    def post(self, request):
        """
        仅重启服务

        仅重启服务
        """
        completed = reload_server_only()
        if completed.returncode == 0:
            return Response()
        else:
            raise APIException(completed.stdout)


class BackupDatabase(APIView):
    permission_classes = [IsAdminUser]

    def post(self, request):
        """
        备份数据库到指定位置

        备份数据库到指定位置
        """
        err_str = backup_database()
        if err_str:
            raise APIException(err_str)
        return Response()


class BackupMedia(APIView):
    permission_classes = [IsAdminUser]

    def post(self, request):
        """
        备份资源到指定位置

        备份资源到指定位置
        """
        err_str = backup_media()
        if err_str:
            raise APIException(err_str)
        return Response()


class CorrectViewSet(CustomGenericViewSet):
    perms_map = {}
    permission_classes = [IsAdminUser]

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def employee(self, request, pk=None):
        """矫正员工信息
        """
        from apps.system.models import User
        from apps.hrm.models import Employee
        for user in User.objects.all():
            Employee.objects.get_or_create(user=user, defaults={
                'user': user,
                'name': user.name,
                'phone': user.phone,
                'belong_dept': user.belong_dept if user.belong_dept else None,
                'post': user.post if user.post else None,
                'type': user.type
            })
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def ticket_sn(self, request, pk=None):
        """矫正工单流水号

        矫正工单流水号
        """
        data = request.data
        from apps.wf.models import Ticket
        from apps.wf.services import WfService
        from django.utils.timezone import localtime
        from apps.opm.models import Opl
        for i in Ticket.objects.get_queryset(all=True).filter(create_time__gte=data['start_time'],
                                                              create_time__lte=data['end_time']).order_by('create_time'):
            sn = WfService.get_ticket_sn(i.workflow, localtime(i.create_time))
            Ticket.objects.filter(id=i.id).update(sn=sn)
            if hasattr(i, 'opl_ticket'):
                opl = getattr(i, 'opl_ticket')
                Opl.objects.filter(id=opl.id).update(number=sn)
        return Response()

    # @action(methods=['post'], detail=False, serializer_class=Serializer)
    # def mgroups_allocate(self, request, pk=None):
    #     """矫正测点分配

    #     矫正测点分配
    #     """
    #     from apps.enm.models import Mpoint
    #     for mpoint in Mpoint.objects.exclude(mgroup=None):
    #         mgroup = mpoint.mgroup
    #         mpoint.mgroups_allocate = [
    #             {'mgroup': mgroup.id, 'mgroup_name': mgroup.name, 'ratio': 1}]
    #         mpoint.save()
    #     return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def mpointstat(self, request, pk=None):
        """矫正测点统计数据

        矫正测点统计数据
        """
        from apps.enm.models import MpointStat
        for item in MpointStat.objects.filter(type__in=['sflog', 'day_s', 'month_s', 'year_s']):
            item.mgroup = item.mpoint.mgroup
            item.save()
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def quastat(self, request, pk=None):
        """矫正质检统计数据

        矫正质检统计数据
        """
        from apps.enm.models import EnStat
        enstats = EnStat.objects.exclude(type='hour_s')
        for item in enstats:
            qua_data = item.qua_data
            if qua_data:
                for x in qua_data:
                    x['rate_pass'] = x['rate_pass']*100
            item.qua_data = qua_data
            item.save()
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def enstat(self, request, pk=None):
        """矫正能源统计数据

        矫正能源统计数据
        """
        from apps.enm.models import EnStat
        for item in EnStat.objects.exclude(sflog=None):
            item.shift = item.sflog.shift
            item.save()
        return Response()

    # @action(methods=['post'], detail=False, serializer_class=Serializer)
    # def global_img_compressed(self, request, pk=None):
    #     """矫正全景压缩照片

    #     矫正全景压缩照片
    #     """
    #     from apps.ecm.models import Event
    #     events = Event.object.filter(global_img_compressed=None).exclude(glboal_img=None)
    #     for event in events:
    #         path, end= event.global_img.split('.')
    #         event.global_img_compressed = path + '_compressed.' + end
    #         event.save()
    #     return Response()


class TestViewSet(CustomGenericViewSet):
    perms_map = {}
    authentication_classes = ()
    permission_classes = ()

    @action(methods=['post'], detail=False, serializer_class=SendSmsSerializer, authentication_classes=())
    def send_sms(self, request, pk=None):
        """发送短信测试

        发送短信测试
        """
        serializer = SendSmsSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        vdata = serializer.validated_data
        res = send_sms(**vdata)
        return Response(res)

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def send_mail(self, request, pk=None):
        """发送邮件测试

        发送邮件测试
        """
        from django.core.mail import send_mail
        send_mail("测试邮件标题", "测试邮件的正文", "909355014@qq.com",
                  ["909355014@qq.com"])
        return Response()

    @action(methods=['post'], detail=False, serializer_class=GenerateVoiceSerializer)
    def generate_voice(self, request, pk=None):
        """文字转语音测试

        文字转语音测试
        """
        serializer = GenerateVoiceSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        vdata = serializer.validated_data
        res = generate_voice(**vdata)
        return Response(res)

    @action(methods=['post'], detail=False, serializer_class=TestTaskSerializer)
    def task(self, request, pk=None):
        """任务派发测试

        任务派发测试
        """
        serializer = TestTaskSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        vdata = serializer.validated_data
        module, func = vdata['func'].rsplit(".", 1)
        m = importlib.import_module(module)
        f = getattr(m, func)
        if vdata['delay']:
            task = f.delay(*vdata.get('args', []), **
                           vdata.get('kwargs', {}))  # 同步执行
            return Response({'task_id': task.id})
        else:
            f(*vdata.get('args', []), **vdata.get('kwargs', {}))
            return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def remind_event(self, request, pk=None):
        """测试事件推送

        测试事件推送
        """
        from apps.ecm.models import Event
        event = Event.objects.get(id='1562718567894487040')
        create_remind(event, params={'area': '生产车间',
                      'employee': '访客石非凡', 'event': '未带安全帽'})
        return Response()

    @auto_log()
    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_snap_only(self, request, pk=None):
        """通道抓图

        通道抓图
        """
        return Response()
        return Response(dhClient.snap(request.data['code']))

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_swip(self, request):
        """
        测试刷脸打卡事件

        测试刷脸打卡事件
        """
        from apps.hrm.services import HrmService
        # data = {'id': 25198, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'nodeCode': '1000096$7$0$0', 'deviceCode': '1000096', 'alarmCode': 'd38c98b842334581a8219b3125ca72d5', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20221123/1/dsf_43aee9e6-6ae2-11ed-9872-e4246c7d1635_42018473_42037732.jpg', 'nodeType': '2', 'alarmDate': 1669187805, 'alarmGrade': 2, 'isSave': False, 'unitType': 7, 'extend': {'deptName': '设备管理部', 'deptIdList': [25], 'acsChannelCode': '1000096$7$0$0', 'maskState': 0, 'enterOrExit': 1, 'openTypeStr': '人脸刷门', 'swingTime': '2022-11-23 15:16:45', 'deviceName': '厂区门入', 'personCode': '8jtfoa', 'openType': '61', 'isOverTemp': False, 'orgCode': '001', 'paperNumber': '61012419850304335X', 'errorDetail': '', 'from': 'evo-accesscontrol', 'id': 1044994923113353216, 'beginTime': 1669187805000, 'acsChannelName': '厂区门入_门禁通道_1', 'cardStatus': '0', 'faceImageUrl': ['http://10.99.5.24:8927/6ad010cf-ce45-11ec-9715-e4246c7d1635/20221123/1/dsf_43aee9e6-6ae2-11ed-9872-e4246c7d1635_42018473_42037732.jpg'], 'orgName': '河北省', 'openFailedCode': 0, 'sex': 1, 'deptId': '25', 'cardType': 0, 'curTemp': 35.5, 'deviceCode': '1000096', 'personName': '谭刚位', 'personImg': '6ae577ee-ce45-11ec-bb54-e4246c7d1635/20221110/1/3313679c-6092-11ed-b963-e4246c7d1635.jpg', 'openResult': 1, 'personId': 673, 'recordImage1': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20221123/1/dsf_43aee9e6-6ae2-11ed-9872-e4246c7d1635_42018473_42037732.jpg', 'category': '0', 'cardNumber': '0525871590', 'rfidType': 0, 'age': 0}, 'alarmType': 61, 'channelSeq': 0, 'orgCode': '001', 'channelName': '厂区门入_门禁通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-accesscontrol', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        # data = {'id': 29870, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'nodeCode': '1002222$7$0$0', 'deviceCode': '1002222', 'alarmCode': '191f4a8d0a2c4b6282448af04df6ec11', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20221124/1/dsf_b8662018-6b9c-11ed-9872-e4246c7d1635_51799202_51816153.jpg', 'nodeType': '2', 'alarmDate': 1669263013, 'alarmGrade': 2, 'isSave': False, 'unitType': 7, 'extend': {'deptName': '安全生产部', 'deptIdList': [28], 'acsChannelCode': '1002222$7$0$0', 'maskState': 3, 'enterOrExit': 3, 'openTypeStr': '人脸刷门', 'swingTime': '2022-11-24 12:10:13', 'deviceName': '办公楼考勤面板', 'personCode': '13911097513', 'openType': '61', 'orgCode': '001', 'paperNumber': '110107196804040335', 'errorDetail': '', 'from': 'evo-accesscontrol', 'id': 1045310360703340544, 'beginTime': 1669263013000, 'acsChannelName': '办公楼考勤面板_门禁通道_1', 'cardStatus': '0', 'faceImageUrl': ['http://10.99.5.24:8927/6ad010cf-ce45-11ec-9715-e4246c7d1635/20221124/1/dsf_b8662018-6b9c-11ed-9872-e4246c7d1635_51799202_51816153.jpg'], 'orgName': '河北省', 'openFailedCode': 0, 'sex': 1, 'deptId': '28', 'cardType': 0, 'deviceCode': '1002222', 'personName': '刘静元', 'personImg': '6ae577ee-ce45-11ec-bb54-e4246c7d1635/20220907/1/d841d821-2e67-11ed-b073-e4246c7d1635.jpg', 'openResult': 1, 'personId': 237, 'recordImage1': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20221124/1/dsf_b8662018-6b9c-11ed-9872-e4246c7d1635_51799202_51816153.jpg', 'category': '0', 'cardNumber': '5973291203', 'rfidType': 0, 'age': 0}, 'alarmType': 61, 'channelSeq': 0, 'orgCode': '001', 'channelName': '办公楼考勤面板_门禁通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-accesscontrol', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        data = {'id': 70781, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'nodeCode': '1002222$7$0$0', 'deviceCode': '1002222', 'alarmCode': '74ac9b9511774388a975dc5daa6ad8b9', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20230419/1/dsf_93e4c0ab-de83-11ed-af40-e4246c7d1635_45533104_45552146.jpg', 'nodeType': '2', 'alarmDate': 1681897834, 'alarmGrade': 2, 'isSave': False, 'unitType': 7, 'extend': {'deptName': '企业管理部', 'deptIdList': [21], 'acsChannelCode': '1002222$7$0$0', 'maskState': 0, 'enterOrExit': 3, 'openTypeStr': '人脸刷门', 'swingTime': '2023-04-19 17:50:34', 'deviceName': '办公楼考勤面板', 'personCode': '13731293508', 'openType': '61', 'orgCode': '001', 'paperNumber': '130634198612035821', 'errorDetail': '', 'from': 'evo-accesscontrol', 'id': 1098304215199125504, 'beginTime': 1681897834000, 'acsChannelName': '办公楼考勤面板_门禁通道_1', 'cardStatus': '0', 'faceImageUrl': [
            'http://10.99.5.24:8927/6ad010cf-ce45-11ec-9715-e4246c7d1635/20230419/1/dsf_93e4c0ab-de83-11ed-af40-e4246c7d1635_45533104_45552146.jpg'], 'orgName': '河北省', 'openFailedCode': 0, 'sex': 1, 'deptId': '21', 'cardType': 0, 'deviceCode': '1002222', 'personName': '李贝', 'personImg': '6ae577ee-ce45-11ec-bb54-e4246c7d1635/20220907/1/9ab9a1eb-2e74-11ed-b073-e4246c7d1635.jpg', 'openResult': 1, 'personId': 331, 'recordImage1': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20230419/1/dsf_93e4c0ab-de83-11ed-af40-e4246c7d1635_45533104_45552146.jpg', 'category': '0', 'cardNumber': '6705501569', 'rfidType': 0, 'age': 0}, 'alarmType': 61, 'channelSeq': 0, 'orgCode': '001', 'channelName': '办公楼考勤面板_门禁通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-accesscontrol', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        HrmService.swipe(data=data)
        return Response()

    @action(methods=['post'], detail=False, serializer_class=TestAlgoSerializer)
    def test_algo(self, request, pk=None):
        """测试算法

        测试算法
        """
        from apps.ai.main import ai_analyse_2
        ret = ai_analyse_2(codes=request.data['codes'],
                           face_img=request.data.get('face_img', None),
                           global_img=request.data.get('global_img', None),
                           is_dahua_pic=request.data.get('is_dahua_pic', True))
        return Response(ret)

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_algo_full(self, request, pk=None):
        """测试算法2

        测试算法2
        """
        mode = request.data.get('mode', 1)
        from apps.ecm.service import dispatch_dahua_event
        data = {'id': None, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '河北省', 'alarmPictureSize': '885977', 'nodeCode': '1002182$1$0$0', 'deviceCode': '1002182', 'alarmCode': '{B55A1489-0064-8D42-B6F4-EFF2DE1DA9B1}', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220831/1/dsf_3c4ef3fe-290f-11ed-884a-e4246c7d1635_55425449_56311426.jpg', 'nodeType': 2, 'deviceName': '192.168.10.155',
                                                                                 'alarmDate': '1661942981', 'alarmGrade': 2, 'isSave': True, 'unitType': 1, 'unitSeq': 0, 'extend': {'params': {'ObjectType': 'Human', 'GroupId': 30.0, 'ObjectSubType': ''}, 'objectSubType': ''}, 'alarmType': 964, 'channelSeq': 0, 'orgCode': '001', 'channelName': '192.168.10.155_视频通道_1', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'admin', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        data = {'id': 1662026969203, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': '44df73ba-a423-4479-af70-1f930b00a7e0', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg', 'nodeType': 2, 'alarmDate': '1662026965', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27257520_27264993.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [
            '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_27264993_27338395.jpg'], 'groupName': '全体人员', 'similarity': 97, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_26915031_27257520.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662026965, 'endTime': 1662026965, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        # data = {'id': 1662032288888, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$25', 'deviceCode': '1000038', 'alarmCode': 'c3df59cd-59d0-4f46-a32c-d2bf7778b37d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg', 'nodeType': 2, 'alarmDate': '1662032288', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44280859_44288676.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220901/1/dsf_80fed821-29c9-11ed-884a-e4246c7d1635_44127174_44280859.jpg', 'eye': 0, 'alarmType': 1001000, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 25, 'szSerialUUID': '', 'channelName': '公司大门口', 'beginTime': 1662032284, 'endTime': 1662032284, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001000, 'channelSeq': 25, 'orgCode': '001001001', 'channelName': '公司大门口', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        data = {'id': 1662099853937, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'c520e09f-4b5d-4d04-be7b-005386a9b835', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg', 'nodeType': 2, 'alarmDate': '1662099849', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57321861_57329128.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [
            '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_57329128_57402530.jpg'], 'groupName': '全体人员', 'similarity': 99, 'sex': 1, 'cardType': 1, 'name': '曹前明', 'devPersonId': '48', 'id': '342422199004040175', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220902/1/dsf_a880f743-2a7e-11ed-884a-e4246c7d1635_56995669_57321861.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662099849, 'endTime': 1662099849, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        if mode == 1:
            data = {'id': 1662786479984, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'nodeCode': '1000038$1$0$24', 'deviceCode': '1000038', 'alarmCode': 'b672731c-4807-47e6-a468-c5f85a68e87d', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg', 'nodeType': 2, 'alarmDate': '1662786477', 'alarmGrade': 2, 'isSave': True, 'extend': {'faceImageUrl': ['6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45588364_45596445.jpg'], 'glass': 0, 'beard': 0, 'candidateInfo': [{'birthday': '2022-8-24', 'faceImageUrl': [
                '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45596445_45673444.jpg'], 'groupName': '全体人员', 'similarity': 81, 'sex': 2, 'cardType': 1, 'name': '石静', 'devPersonId': '47', 'id': '371324199502156548', 'type': 0}], 'sex': 0, 'occurrenceCount': 0, 'deviceCode': '1000038', 'globalScenePicUrl': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220910/1/dsf_2c1150b4-309b-11ed-884a-e4246c7d1635_45288246_45588364.jpg', 'eye': 0, 'alarmType': 1001003, 'perFlag': -1, 'mouth': 0, 'feature': [], 'isHit': True, 'channelSeq': 24, 'szSerialUUID': '', 'channelName': '窑头平台值班室', 'beginTime': 1662786477, 'endTime': 1662786477, 'age': -1, 'mask': 0}, 'unitType': 1, 'alarmType': 1001003, 'channelSeq': 24, 'orgCode': '001001001', 'channelName': '窑头平台值班室', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'evo-face', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        elif mode == 2:
            data = {'id': None, 'category': 'alarm', 'method': 'alarm.msg', 'info': {'orgName': '曲阳县金隅水泥厂', 'alarmPictureSize': '592887', 'nodeCode': '1002191$1$0$0', 'deviceCode': '1002191', 'alarmCode': '{DBF64A47-DA5B-F147-B474-E74F54E4B6E9}', 'alarmPicture': '6ad010cf-ce45-11ec-9715-e4246c7d1635/20220923/1/dsf_b834ecae-3ad7-11ed-85c0-e4246c7d1635_43351055_43943942.jpg', 'nodeType': 2, 'deviceName': '192.168.10.177', 'alarmDate': '1663897556', 'alarmGrade': 2, 'isSave': True, 'unitType': 1, 'unitSeq': 0, 'extend': {'params': {'ObjectType': 'Unknown',
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       'nResetID': 0.0, 'HFOV': 0.0, 'stuPTZPosition': {'nPositionX': 0.0, 'nPositionY': 0.0, 'nZoom': 0.0}, 'Objects': [{'stuBoundingBox': {'nTop': 2616.0, 'nBottom': 3288.0, 'nLeft': 4352.0, 'nRight': 4768.0}}], 'nRuleID': 2.0, 'GroupId': 380.0, 'ObjectSubType': '', 'VFOV': 0.0}, 'objectSubType': ''}, 'alarmType': 303, 'channelSeq': 0, 'orgCode': '001001001', 'channelName': '二道门地中衡', 'alarmStat': 1, 'isEvent': True}, 'subsystem': 'admin', 'userIds': None, 'sid': None, 'domainId': None, 'infoArray': None, 'protocol': None}
        dispatch_dahua_event(data=data)
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_snap(self, request, pk=None):
        """测试抓图识别

        测试抓图识别
        """
        code = request.data['code']
        codes = request.data['codes']
        opl_id = request.data.get('opl', None)
        vc = TDevice.objects.get(code=code)
        opl = Opl.objects.get(id=opl_id) if opl_id else None
        snap_and_analyse(vc, codes, opl)
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_snap_task(self, request, pk=None):
        """测试抓图识别任务

        测试抓图识别任务
        """
        code = request.data['code']
        task = opl_task.delay([code], '1568880208688320512')
        task_id = task.task_id
        test_snap_list = cache.get('test_snap_task', [])
        test_snap_list.append(task_id)
        cache.set('test_snap_task', test_snap_list)
        return Response({'test_snap_task': task_id})
    
    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def stop_celery_task(self, request, pk=None):
        """"
        关闭重跑重跑能源计算任务
        """
        from server.celery import celery_control
        celery_control.revoke(request.data['task_id'], terminate=True)
        return Response()


    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def close_snap_task(self, request, pk=None):
        """关闭抓图识别任务

        关闭抓图识别任务
        """
        test_snap_list = cache.get('test_snap_task', [])
        from celery.app.control import Control
        from server.celery import app
        celery_control = Control(app=app)
        # 关闭作业视频监控任务
        for i in test_snap_list:
            celery_control.revoke(i, terminate=True)
        cache.set('test_snap_task', [])
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_loc_change(self, request, pk=None):
        """位置信息改变

        位置信息改变
        """
        data = {'buildId': '204878', 'floorNo': 'Floor1', 'userId': '1918B2001A26', 'timestampMillisecond': 1663749630302, 'xMillimeter': 314364, 'yMillimeter': 362752,
                'zMillimeter': 0, 'pointProperties': 0, 'locationType': 1, 'status': 0, 'src': 0, 'longitude': 114.63020038067505, 'latitude': 38.81357371331778}
        res = loc_change(data=data)
        return Response(res)

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_one_key_alarm(self, request, pk=None):
        """一键报警事件

        一键报警事件
        """
        data = {'buildId': '204878', 'mac': '1918B20019F5',
                'time': 1663067822887, 'event': 'alarm', 'alarmTypeName': '一键报警'}
        res = handle_xx_event(name='one_key_alarm', data=data)
        return Response(res)

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_rail_in(self, request, pk=None):
        """测试围栏进入

        测试围栏进入
        """
        data = {'railId': '80fe94bff7b240aa893976965197487c', 'userId': '1918B20019F5', "railName": "二道门",
                'time': 1663067822887, "type": 1, "buildId": "204878", "floorNo": "Floor1"}
        res = rail_in(data=data)
        return Response(res)

    @action(methods=['post'], detail=False, serializer_class=AreaManSerializer)
    def test_area_man(self, request, pk=None):
        """测试区域超员/缺员事件

        测试区域超员/缺员事件
        """
        res = update_count_people(i=Area.objects.get(id=request.data['area']))
        return Response(res)

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def correct_rail(self, request, pk=None):
        pass

    @action(methods=['post'], detail=False, serializer_class=SpeakerSerializer)
    def test_speaker(self, request, pk=None):
        spClient.speak(path=request.data['text_or_path'], sns=request.data['sns'],
                        v_num=2)
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_event_speak(self, request, pk=None):
        from apps.ecm.models import Event
        from apps.ecm.service import save_voice_and_speak
        save_voice_and_speak(Event.objects.get(id=request.data['event']))
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def test_not_in_place(self, request, pk=None):
        opl = request.data.get('opl')
        check_not_in_place(opl=Opl.objects.get(id=opl))
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def correct_gender(self, request, pk=None):
        objs = Employee.objects.get_queryset(all=True).all()
        for i in objs:
            if i.id_number:
                ret = get_info_from_id(i.id_number)
                i.gender = ret['gender']
                i.save()
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer)
    def send_wx_msg(self, request, pk=None):
        """微信模板消息发送测试

        微信模板消息发送测试
        """
        data = {
            "touser": "ocAnm5vab6QGOnf2dqpuUZGJ0xyw",
            "template_id": "wczl-hB_bs8CpxwO8_KZuogSTPFXqhBxf8C5HjKl2M4",
            "url": "http://weixin.qq.com/download",
            #    "miniprogram":{
            #      "appid":"xiaochengxuappid12345",
            #      "pagepath":"index?foo=bar"
            #    },
            "client_msg_id": "MSG_000001",
            "data": {
                "first": {
                   "value": "恭喜你购买成功！",
                   "color": "#173177"
                },
            }
        }
        # url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token'+wxClient.token
        # print(url)
        # rt = requests.post(url=url, json=data).text
        res = wxClient.send_tem_msg(data=data)
        return Response(res)

    # @action(methods=['post'], detail=False, serializer_class=Serializer, permission_classes=[])
    # @transaction.atomic
    # def correct_face_card(self, request, pk=None):
    #     from apps.hrm.tasks import correct_card_time
    #     correct_card_time()
    #     return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer, permission_classes=[])
    @transaction.atomic
    def correct_data(self, request, pk=None):
        """修正数据

        修正数据
        """
        for i in Transition.objects.all():
            if i.condition_expression:
                pass
            else:
                i.condition_expression = []
                i.save()
        # wf = Workflow.objects.get(id='1544859644185415680')
        # objs = Workflow.objects.filter(key__istartswith='opl_').exclude(id='1544859644185415680')
        # for i in objs:
        #     for s in State.objects.filter(workflow=wf):
        #         sta = State()
        #         sta.id = idWorker.get_id()
        #         sta.workflow = i
        #         for f in State._meta.fields:
        #             if f.name not in ['workflow', 'create_time', 'update_time', 'id']:
        #                 setattr(sta, f.name, getattr(s, f.name))
        #         sta.save()
        #     for t in Transition.objects.filter(workflow=wf):
        #         tr = Transition()
        #         tr.id = idWorker.get_id()
        #         tr.workflow = i
        #         for f in Transition._meta.fields:
        #             if f.name not in ['workflow', 'create_time', 'update_time', 'id']:
        #                 setattr(tr, f.name, getattr(t, f.name))
        #         tr.save()
        return Response()

    @action(methods=['post'], detail=False, serializer_class=CleanDataSerializer,
            authentication_classes=[JWTAuthentication, BasicAuthentication, SessionAuthentication],
            permission_classes=[IsAdminUser])
    def clean_data(self, request, pk=None):
        """清空数据

        清空数据
        """
        datas = request.data['datas']
        from apps.wf.models import Ticket
        from apps.hrm.models import Employee
        from apps.system.models import User, Dept
        if 'visit' in datas:
            # 访客
            from apps.vm.models import Visit, Visitor
            Visit.objects.get_queryset(all=True).delete(soft=False)
            Visitor.objects.get_queryset(all=True).delete(soft=False)

            Ticket.objects.get_queryset(all=True).filter(
                workflow__key='visit').delete(soft=False)

            Employee.objects.get_queryset(all=True).filter(
                type='visitor').delete(soft=False)

            User.objects.get_queryset(all=True).filter(
                type='visitor').delete(soft=False)
        if 'rpm' in datas:
            from apps.rpm.models import Rparty
            Rparty.objects.get_queryset(all=True).delete(soft=False)
            Ticket.objects.get_queryset(all=True).filter(
                workflow__key='rpj').delete(soft=False)
            Employee.objects.get_queryset(all=True).filter(
                type='remployee').delete(soft=False)
            User.objects.get_queryset(all=True).filter(
                type='remployee').delete(soft=False)
            Dept.objects.get_queryset(all=True).filter(
                type='rparty').delete(soft=False)
        if 'event' in datas:
            from apps.ecm.models import Event
            Event.objects.all().delete()
        if 'opm' in datas:
            from apps.opm.models import Operation
            Operation.objects.all().delete()
            Ticket.objects.get_queryset(all=True).filter(
                workflow__key__contains='opl_').delete(soft=False)
        if 'ptask' in datas:
            from django_celery_results.models import TaskResult
            TaskResult.objects.filter(task_name__in=['apps.vm.tasks.close_visit_by_leave_time',
                                                     'apps.rpm.tasks.close_rpj_by_leave_time']).delete()
        if 'mes' in datas:
            from apps.inm.models import MaterialBatch, MIO
            from apps.mtm.models import Material, RoutePack
            from apps.wpmw.models import Wpr
            from apps.wpm.models import WMaterial, Mlog, Handover, BatchSt
            from apps.pum.models import PuOrder
            from apps.sam.models import Order
            from apps.pm.models import Utask, Mtask
            from apps.qm.models import Ftest, FtestWork
            from apps.wf.models import Ticket
            MaterialBatch.objects.all().delete()
            MIO.objects.all().delete()
            Wpr.objects.all().delete()
            WMaterial.objects.all().delete()
            Utask.objects.all().delete()
            Mtask.objects.all().delete()
            Mlog.objects.all().delete()
            PuOrder.objects.get_queryset(all=True).delete()
            Order.objects.get_queryset(all=True).delete()
            Handover.objects.all().delete()
            Ftest.objects.all().delete()
            FtestWork.objects.all().delete()
            BatchSt.objects.all().delete()
            Ticket.objects.get_queryset(all=True).delete()
        return Response()

    @action(methods=['post'], detail=False, serializer_class=Serializer, permission_classes=[])
    def test_cal(self, request, pk=None):
        from apps.wpm.tasks import cal_exp_duration_sec
        cal_exp_duration_sec('3397169058570170368')
        return Response()


html_str = """
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WebView 扫码</title>
</head>
<body>
<button onclick="openScanner()">扫码</button>
<p>扫描结果: <span id="result"></span></p>

<script>
    function openScanner() {
        if (window.Android) {
            window.Android.openScanner();
        } else {
            alert("当前环境不支持扫码");
        }
    }

    function onScanResult(data) {
        document.getElementById("result").innerText = data;
    }
</script>
</body>
</html>
"""
def testScanHtml(request):
    return HttpResponse(html_str)