<?php

namespace Application\Controller;

use Application\Common\StatusCode;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\DB\Dictionary\Form;
use Application\Form\item\LogicModel;
use Application\Form\item\patient\PatientFormModel;
use Application\Form\LogicFormModel;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\CheckLogic\CheckLogicApplication;
use Application\Service\Extension\CheckLogic\ExpressionGenerator;
use Application\Service\Extension\Formatter\Formatter;
use Application\Service\Extension\Formatter\LogicErrorFormatter;
use Application\Service\Extension\Formatter\LogicErrorReplyFormatter;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use Application\Service\Extension\Validator\ValidatorApplication;
use Laminas\Db\ResultSet\ResultSet;
use Laminas\Db\Sql\Expression;
use Laminas\Db\Sql\Predicate\IsNotNull;
use Laminas\Db\Sql\Predicate\Like;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Sql;
use Laminas\Db\Sql\Where;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Stdlib\ArrayUtils;
use Laminas\ServiceManager\ServiceManager;

class LogicController extends AbstractActionController // BaseController
{
    public function __get($name)
    {
        if ($name === 'validator') {
            $this->validator = new ValidatorApplication();
            return $this->validator;
        }
    }

    /** @var int 5mc */
    public const ITEM_ID = 1085;


    public function indexAction()
    {
        $query = Laminas::$serviceManager->itemPatientFormLogic->fetchAllWithPagination([
            'columns' => ['id', 'expression', 'expression_hash', 'generator'],
            'where' => ['is_del' => 0, 'item_id' => $this->params()->fromPost('item_id')]
        ]);

        foreach ($query['data'] as &$v) {
            $g = unserialize($v['generator']);
            $v['usingVars'] = '';
            $v['note'] = $g->note;
            unset($v['generator']);
        }
        return $this->RenderApiJson()->Success($query['data'], 'OK', [
            'total' => $query['count']
        ]);
    }

    public function configAction()
    {
        $conditions = function () {
            $r = [];
            foreach (CheckLogicApplication::CONDITIONS as $k => $v) {
                $r[] = [
                    'label' => $k,
                    'value' => $v,
                ];
            }
            return $r;
        };
        return $this->RenderApiJson()->Success([
            'conditions' => $conditions(),
            'functions' => [
                [
                    'label' => '_date(要处理的时间): 时间处理函数。',
                ],
                [
                    'label' => '_visit(访视点标识, 字段变量名): 切换访视点',
                ]
            ],
            'checktime_id' => Laminas::$serviceManager->itemChecktime->fetchAll([
                'columns' => ['id', 'check_name'],
                'where' => [
                    'item_id' => self::ITEM_ID,
                ]
            ])
        ], 'OK');
    }

    public function viewAction()
    {
        $query = Laminas::$serviceManager->itemPatientFormLogic->fetchOne([
            'columns' => ['expression', 'generator'],
            'where' => ['id' => $this->params()->fromPost('id'), 'is_del' => 0]
        ]);

        $g = unserialize($query['generator']);
        $query['pointer'] = $g->pointer ?? [];
        $query['note'] = $g->note ?? '';
        unset($query['generator']);

        return $this->RenderApiJson()->Success($query ?? [], 'OK');
    }

    public function deleteAction()
    {
        $id = $this->params()->fromPost('id');
        Laminas::$serviceManager->itemPatientFormLogic->update(['is_del' => 1], ['id' => $id]);
        return $this->RenderApiJson()->Success();
//        Laminas::$serviceManager->itemPatientFormLogicError->update(['is_del' => 1], [$]);
    }

    public function createAction()
    {
        $v = new ValidatorApplication();
        $v->attach(
            [['item_id', 'expression', 'pointer'], 'required']
        );

        if (!$v->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $v->getFirstErrorToString());
        }

        $model = new LogicModel($v);
        if (!$v->attributes['id']) {
            $model->create();
        } else {
            $model->edit();
        }

        return $this->RenderApiJson()->Success();
    }


    public function formListAction()
    {
        $isCustom = false;
        $itemId = $this->params()->fromPost('item_id');
        $expressionId = $this->params()->fromPost('expression_id');
        $query = Laminas::$serviceManager->itemPatientFormLogic->fetchOne([
            'where' => ['expression_hash' => $this->params()->fromPost('expression_id')]
        ]);

        // 手动质疑
        if (!$query) {
            $isCustom = true;
            $err = Laminas::$serviceManager->itemPatientFormLogicError->fetchOne([
                'where' => ['id' => $expressionId]
            ]);

            $generator = new Class($err) {
                public array $pointer = [];

                public function __construct($err)
                {
                    $this->pointer = [
                        [$err['checktime_id'], $err['form_id']]
                    ];
                }
            };
        } else {
            /** @var ExpressionGenerator $generator */
            $generator = unserialize($query['generator']);
            $err = Laminas::$serviceManager->itemPatientFormLogicError->fetchOne([
                'where' => ['expression_id' => $expressionId]
            ]);
        }

        $formList = [];
        $r = [];
        $c = [];

        foreach ($generator->pointer as $item) {
            // 去重
            if (in_array($item[1], $c)) {
                continue;
            }
            $c[] = $item[1];
            $getCheckTimeId = function ($val) use ($item, $itemId, $isCustom) {
                if ($isCustom === true) {
                    return $val;
                }

                return ($item[0] == 'AE' ?
                    Laminas::$serviceManager->itemForm->fetchOne(['where' => ['group_id' => FormGroup::AE, 'is_del' => 0]])['id'] :
                    Laminas::$serviceManager->itemChecktime->fetchOne(['where' => ['var_name' => $item[0], 'item_id' => $itemId, 'is_del' => 0]])['id']);
            };
            $formList['checktime_id'] = $getCheckTimeId($item[0]);

            $getFormInfo = function ($val) use ($isCustom) {

                if ($isCustom === true) {
                    return Laminas::$serviceManager->itemForm->fetchOne([
                        'columns' => ['name as label', 'id'],
                        'where' => [
                            'id' => $val,
                        ]
                    ]);
                }

                return Laminas::$serviceManager->itemForm->fetchOne([
                    'columns' => ['name as label', 'id'],
                    'where' => [
                        'var_name' => $val,
                        'item_id' => $this->params()->fromPost('item_id')
                    ]
                ]);
            };
            $formInfo = $getFormInfo($item[1]);
            $formList['id'] = $formInfo['id'];
            $formList['label'] = $formInfo['label'];
            $formList['item_id'] = $err['item_id'] ?? 0;
            $formList['itemsig_id'] = $err['sign_id'] ?? 0;
            $r[] = $formList;
        }

        return $this->RenderApiJson()->Success($r);
    }

    public function formViewAction()
    {
        $errorInfo = Laminas::$serviceManager->itemPatientFormLogicError->fetchOne([
            'where' => [
                'id' => $this->params()->fromPost('error_id')
            ]
        ]);

        $v = new ValidatorApplication();
        $v->attributes['patient_id'] = $errorInfo['patient_id'];
        $v->attributes['item_id'] = $this->params()->fromPost('item_id');
        $model = new PatientFormModel($v);

        $itemFormData = Laminas::$serviceManager->itemForm->fetchOne([
            'where' => ['id' => $v->attributes['form_id']]
        ]);

        if ($errorInfo['is_report'] && $itemFormData['type'] == Form::FORM_TYPE_MULTI) {
            $model->contentPrimaryKey = $errorInfo['formcontent_id'];
            $model->setContentId($errorInfo['formcontent_id']);
        }else {
            $model->setContentId($errorInfo['multi_id']);
        }

        $model->setCheckLogic(true);
        /*$isAe = Laminas::$serviceManager->itemForm->fetchOne([
            'where' => ['id' => $v->attributes['form_id']]
        ])['group_id'];*/

        // AE
        if ($itemFormData['group_id']) {
            $aeContent = [];
            $r = Laminas::$serviceManager->itemPatientAeContent->fetchAll(['where' => ['id' => $errorInfo['multi_id']]]);
            foreach ($r as $v) {
                $branch = $v['branch'];
                $contentId = Laminas::$serviceManager->itemCsaeRelation->fetchOne(['where' => ['branch' => $branch]])['content_id'];
                $aeContent[] = Laminas::$serviceManager->itemPatientAeContent->fetchOne(['where' => ['id' => $contentId]]);
            }
        }

        $attach = [];
        $res = ($itemFormData['group_id'] == FormGroup::AE ? $model->viewAe($aeContent ?? []) : $model->view());
        if($errorInfo['is_report'] && $itemFormData['type'] == Form::FORM_TYPE_MULTI && count($res) > 0) {
            $res = current($res);
        }
        if ($model->getAnnexLock()) {
            $attach['annexData'] = $model->getAnnexData();
        }

        if ($itemFormData['group_id'] != FormGroup::AE && SDMHelper::app()->form->getType($v->attributes['form_id']) == Form::FORM_TYPE_SINGLE && $res) {
            $res['childData'] = isset($res['childData']) && !empty($res['childData']) ? json_decode($res['childData'],true) : [];
            if(!empty($res['childData'])){
                $aeResults = Laminas::$serviceManager->itemCsae->fetchCheckFieldAeData([
                    'item_id'=>$v->attributes['item_id'],
                    'itemsig_id'=>[$v->attributes['itemsig_id']],
                    'patient_id'=>[$v->attributes['patient_id']],
                    'form_id'=>[$v->attributes['form_id']],
                    'type'=>1
                ]);
                $aeResultArr = isset($aeResults[$res['id']]) && !empty($aeResults[$res['id']]) ? $aeResults[$res['id']] : [];
                unset($aeResults);
                foreach($res['childData'] as $data_judge_key=>$data_judge){
                    $res['childData'][$data_judge_key]['normal_type'] = !empty($data_judge['normal_type']) ? $data_judge['normal_type'] : '';
                    $res['childData'][$data_judge_key]['parentProp'] = $data_judge_key;
                    $res['childData'][$data_judge_key]['aeResultList'] = [];
                    $res['childData'][$data_judge_key]['disabled'] = true;
                    if($data_judge['normal_type'] == 2){
                        $res['childData'][$data_judge_key]['aeResultList'] = isset($aeResultArr[$data_judge['field_id']]) && isset($aeResultArr[$data_judge['field_id']]['show_ae']) && !empty($aeResultArr[$data_judge['field_id']]['show_ae']) ? $aeResultArr[$data_judge['field_id']]['show_ae'] : [];
                    }
                }
                unset($aeResultArr);
            }
        }
        return $this->RenderApiJson()->Success($res, 'OK', $attach);
    }

    public function formDetailAction()
    {
        $model = new PatientFormModel();
        $content = [];

        if (Laminas::$serviceManager->itemForm->fetchOne([
                'where' => ['id' => $this->params()->fromPost('form_id')]
            ])['group_id'] == FormGroup::AE) {
            $content = Laminas::$serviceManager->itemPatientAeContent->fetchOne(['where' => ['id' => $this->params()->fromPost('id')]]);
            $branch = $content['branch'];
            $contentId = Laminas::$serviceManager->itemCsaeRelation->fetchOne(['where' => ['branch' => $branch]])['content_id'];
            $content = Laminas::$serviceManager->itemPatientAeContent->fetchOne(['where' => ['id' => $contentId]]);
        }
        return $this->RenderApiJson()->Success($model->viewById($this->params()->fromPost('id'), $content));
    }

    public function varListAction()
    {
        $query = Laminas::$serviceManager->itemFormField->fetchAll([
            'columns' => ['var_name', 'id', 'name'],
            'where' => ['item_id' => self::ITEM_ID, 'parent' => 0, new IsNotNull('parent')]
        ]);
        foreach ($query as &$item) {
            $item['label'] = "{$item['name']} - {{$item['var_name']}}";
            $item['value'] = " `{$item['var_name']}` ";
            unset($item['name']);
            unset($item['var_name']);
        }

        return $this->RenderApiJson()->Success($query, 'OK');
    }

    public function varListV2Action()
    {
        $itemId = $this->params()->fromPost('item_id', 0);
        $aeData = Laminas::$serviceManager->itemForm->fetchOne(['where' => ['group_id' => FormGroup::AE, 'item_id' => $itemId]]);
        $allCheckTime = Laminas::$serviceManager->itemChecktime->fetchAll([
            'columns' => ['check_name as label', 'var_name as value', 'id'],
            'where' => [
                'item_id' => $itemId,
                new Operator('field_id', Operator::OP_NE, 0)
            ]
        ]);
        // 设置ae检查点
        $allCheckTime[] = [
            'label' => 'AE',
            'value' => 'AE',
            'id' => $aeData['id'],
        ];


        $relation = Laminas::$serviceManager->itemCheckcontent->fetchAll([
            'where' => ['item_id' => $itemId]
        ]);

        // 设置ae表单数据
        $relation[] = [
            'check_id' => $aeData['id'],
            'form_id' => $aeData['id'],
        ];

        $query = Laminas::$serviceManager->itemFormField->fetchAll([
            'columns' => ['var_name', 'name', 'form_id'],
            'where' => [
                'item_id' => $itemId,
                'parent' => 0,
                new IsNotNull('parent'),
                new Operator('var_name', Operator::OP_NE, '')
            ],
            'order' => ['form_id']
        ]);


        $res = [];
        // 设置ae字段数据
        $res[$aeData['id']] = [
            'label' => '不良事件',
            'value' => $aeData['var_name'],
        ];

        foreach ($query as $item) {
            if (!isset($res[$item['form_id']])) {
                $formInfo = Laminas::$serviceManager->itemForm->fetchOne(['where' => ['id' => $item['form_id'], new Operator('var_name', Operator::OP_NE, ''), 'is_del' => 0]]);
                if (!$formInfo) {
                    continue;
                }
                $res[$item['form_id']]['label'] = "{$formInfo['name']}" ?? '';// "{$formInfo['name']} - {$formInfo['var_name']}" ?? '';
                $res[$item['form_id']]['value'] = $formInfo['var_name'] ?? '';
                if ($formInfo['group_id'] == FormGroup::CHECK_OCR) {
                    $res[$item['form_id']]['children'][] = [
                        'label' => '检查日期',// '{OCR_CHECK_TIME} - 检查日期',
                        'value' => "OCR_CHECK_TIME",
                    ];
                }
            }
            $res[$item['form_id']]['children'][] = [
                'label' => "{$item['var_name']} - {$item['name']}",// "{{$item['var_name']}} - {$item['name']}",
                'value' => "{$item['var_name']}",
            ];
        }
//        var_dump($res);die;

//        $isAppend = [];
        foreach ($allCheckTime as &$checkTime) {
            foreach ($relation as $v) {
                if ($v['check_id'] == $checkTime['id'] && isset($res[$v['form_id']])) {
                    $checkTime['children'][] = $res[$v['form_id']];
//                    $isAppend[] = $checkTime['value'];
                }
            }
        }
//        var_dump($allCheckTime);die;
        return $this->RenderApiJson()->Success(array_values($allCheckTime), 'OK');
    }

    public function executeAction()
    {
        $ex = Laminas::$serviceManager->itemPatientFormLogic->fetchOne([
            'where' => [
                'id' => $_POST['id']
            ]
        ]);

        $generator = unserialize($ex['generator']);
        $app = new CheckLogicApplication();
        $app::$debugMode = false;
        $app->setItemId($ex['item_id'])
            ->setGenerator($generator)
            ->execute();

        return $this->RenderApiJson()->Success();
    }

    public function errorListAction()
    {
        $filter = [];

        if ($_POST['expression_id']) {
            $filter [] = ['expression_id' => $_POST['expression_id']];
        }
        $query = Laminas::$serviceManager->itemPatientFormLogicError->fetchAllWithPagination([
            'order' => ['sign_id ASC'],
            'columns' => ['is_closed as status', 'create_time', 'expression_note', 'patient_id', 'expression_id', 'id', 'is_queried', 'is_reply', 'error_type'],
            'where' => ArrayHelper::merge([
                'item_id' => $this->params()->fromPost('item_id'),
                'is_del' => 0,
            ], $filter)
        ]);

        $formatter = new Formatter();
        $formatter::format($query['data'], new LogicErrorFormatter());

        return $this->RenderApiJson()->Success($query['data'], 'OK', ['total' => $query['count']]);
    }


    public function queriedErrorListAction()
    {
        if($this->request->isPost()){
            $limit          = $this->params()->fromPost('limit', 20);
            $page           = $this->params()->fromPost('page', 1);
            $offset         = intval(($page - 1) * $limit);
            $item_id        = $this->params()->fromPost('item_id', 0);//项目ID
            $status         = $this->params()->fromPost('status', '');//状态
            $patient_number = $this->params()->fromPost('patient_number', ''); //受试者筛选号
            $patient_number = !empty($patient_number) ? trim($patient_number) : '';
            $error_message  = $this->params()->fromPost('error_message', ''); //质疑描述
            $error_message  = !empty($error_message) ? trim($error_message) : '';
            $patient_id     = $this->params()->fromPost('patient_id', 0); //受试者ID
            $expression_id  = $this->params()->fromPost('expression_id', 0);
            $user_role      = $this->params()->fromPost('user_role', 0); //提出质疑的角色
            $apply_note      = $this->params()->fromPost('apply_note', 0); //提出的人员姓名
            $itemsig_id      = $this->params()->fromPost('itemsig_id', 0); //中心ID
            $form_id      = $this->params()->fromPost('form_id', 0); //中心ID
            $serch_user = $this->params()->fromPost('serch_user', '');//提出质疑人员ID
            $serch_user = $serch_user != '' ? trim($serch_user,',') : '';

            if(empty($item_id) || empty($itemsig_id)){
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'参数有误！');
            }

            //角色是设置在大项目下的 当前传的值是小项目 getOneFileldVal
            $fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
                'id' => $item_id,
            ]);

            $where = [
                'is_del' => 0,
                'item_id' => $item_id,
                'sign_id' => $itemsig_id,
            ];

            $conditions = [];
            switch ($status) {
                case 'isReply':
                    $conditions[] = 'is_reply = 1';
                    $conditions[] = 'is_closed = 0';
                    break;
                case 'isClosed':
                    $conditions[] = 'is_closed = 1';
                    break;
                default:
                    $conditions[] = 'is_reply = 0';
                    $conditions[] = 'is_closed = 0';
            }
            // 将条件连接成字符串
            $where = ArrayUtils::merge($where, $conditions);

            //获取质疑的所有提出人员ID
            $select_users = $userArr = [];
            $questionUserArr = $this->LocalService()->itemPatientFormLogicError->fetchCol('create_user_id',$where);
            if(!empty($questionUserArr)){
                $questionUserArr = array_values($questionUserArr); //过滤掉空值
                if(!empty($questionUserArr)){
                    $select_users = $this->LocalService()->adminUser->fetchAll([
                        'where'=> [
                            'id' => $questionUserArr
                        ],
                        'columns'=>['value'=>'id','label'=>'realname']
                    ]);
                }

                if(!empty($select_users)){
                    foreach($select_users as $select_user){
                        $userArr[$select_user['value']] = $select_user['label'];
                    }
                }
                if(in_array(0,$questionUserArr)){
                    $select_users[] = [
                        'value'=>'0',
                        'label'=>'系统'
                    ];
                }
            }
            unset($questionUserArr);

            if(empty($patient_id) && !empty($patient_number)){
                //查询受试者ID
                $patient_id = $this->LocalService()->patient->fetchCol('id', [
                    "patient_number REGEXP ? and is_del = 0" => $patient_number,
                ]);
                if(!empty($patient_id)){
                    $where['patient_id'] = StringHelper::toArray($patient_id);
                }else{
                    $where = [
                        'id' => 0,
                    ];
                }
            }else{
                if(!empty($patient_id)){
                    $where['patient_id'] = $patient_id;
                }
            }


            if (!empty($error_message)) {
                if($error_message == '人工'){
                    $where['error_type'] = 1;
                }elseif($error_message == '系统'){
                    $where['error_type'] = 0;
                }else{

                    $pointerWhere = new Where();
                    $pointerWhere->equalTo('is_del',0)
                        ->equalTo('item_id',$item_id)
                        ->like('error_message',"%{$error_message}%");
                    $error_id = $this->LocalService()->itemPatientFormLogicErrorPointer->fetchCol('error_id',$pointerWhere);

//                    $error_id = $this->LocalService()->itemPatientFormLogicErrorPointer->fetchCol('error_id',[
//                        new Expression("error_message REGEXP ? ", $error_message),
//                        'is_del' => 0,
//                    ]);

                    if(!empty($error_id)){
                        $where['id'] = StringHelper::toArray($error_id);
                    }else{
                        $where = [
                            'id' => 0,
                        ];
                    }
                }
            }

            //质疑回复内容检索
            if(!empty($apply_note)){
                $error_id = $this->LocalService()->itemPatientFormLogicErrorQuery->fetchCol('error_id', [
                    'is_reply' => 1,
                    new Like('content', "%{$apply_note}%"),
                    'is_del' => 0,
                ]);
                if(!empty($error_id)){
                    $where['id'] = StringHelper::toArray(array_unique($error_id));
                }else{
                    $where = [
                        'id' => 0,
                    ];
                }
            }

            if(!empty($expression_id)){
                $where['expression_id'] = $expression_id;
            }

            if(!empty($form_id)){
                $where['form_id'] = StringHelper::toArray($form_id);
            }

            //提出质疑人员
            if($serch_user != ''){
                $where['create_user_id'] = StringHelper::toArray($serch_user);
            }
            unset($serch_user);

            //提出质疑角色
            if(!empty($user_role)){
                $adminUserId = [];
                //查询当前项目下该角色的人员id
                $signatory_userArr = $this->LocalService()->realRole->getRolUser();
                $itemRoleArr = isset($signatory_userArr[$fid][$user_role]) && !empty($signatory_userArr[$fid][$user_role]) ? $signatory_userArr[$fid][$user_role] : [];
                if(!empty($itemRoleArr)){
                    //角色下的人员ID与对应手机号数组
                    $phoneSigidArr = $this->LocalService()->signatoryUser->getFiledRelation([], ['id','user_tel'], 'id', 1);
                    //根据手机号查询人员ID数组
                    $user_datas = $this->LocalService()->adminUser->fetchDataByKey([],['id','mobile'],'id',['mobile'=>0]);
                    $user_datas = !empty($user_datas['mobile']) ? $user_datas['mobile'] : [];
                    foreach ($itemRoleArr as $itemRole){
                        $role_phone  = isset($phoneSigidArr[$itemRole])&&!empty($phoneSigidArr[$itemRole]) ? $phoneSigidArr[$itemRole]['user_tel'] : '';
                        $roleUser_id =isset($user_datas[$role_phone])&&!empty($user_datas[$role_phone]) ? $user_datas[$role_phone]['id'] : '';
                        if(!empty($roleUser_id)){
                            $adminUserId[] = $roleUser_id;
                        }
                    }
                }
                unset($itemRoleArr);
                unset($signatory_userArr);

                if(!empty($adminUserId)){
                    $where['create_user_id'] = StringHelper::toArray($adminUserId);
                }else{
                    $where = "id <0";
                }
                unset($adminUserId);
            }
            unset($user_role);


            //获取查询条件
            $cond = [
                'where'=>$where,
                'columns'=>['is_closed as status','checktime_id','form_id','expression_id', 'create_time', 'expression_note', 'patient_id','id', 'is_queried', 'is_reply', 'error_type', 'submit_role', 'create_user_id','sign_id'],
                'order'=>['create_time desc'],
            ];

            $total = $this->LocalService()->itemPatientFormLogicError->getCount($where);
            $datas = $this->LocalService()->itemPatientFormLogicError->fetchAllWithPagination($cond)['data'] ?? [];

            $stageDatas = Laminas::$serviceManager->itemResearchstage->fetchCol('stage_name',[
                'is_del' => 0,
                'item_id' => $item_id,
            ]);

            $checktimeDatas = $this->LocalService()->itemChecktime->fetchAll(['where'=> [
                'item_id' => $item_id,
                'is_del' => 0,
            ],'columns'=>['id','check_name','stage_id']]);
            $checktimeDatas = ArrayHelper::index($checktimeDatas,'id');

            $formDatas = $this->LocalService()->itemForm->fetchCol('name', [
                'item_id' => $item_id,
                'is_del' => 0,
            ]);
            if(!empty($datas)){
                foreach($datas as $k=>$v){
                    if(isset($checktimeDatas[$v['checktime_id']]) && isset($checktimeDatas[$v['checktime_id']]['stage_id'])){
                        $datas[$k]['check_name'] =  $stageDatas[$checktimeDatas[$v['checktime_id']]['stage_id']].'/'.$checktimeDatas[$v['checktime_id']]['check_name'];
                    }else{
                        $datas[$k]['check_name'] = $checktimeDatas[$v['checktime_id']]['check_name'];
                    }
                    $datas[$k]['form_name'] = $formDatas[$v['form_id']];

                    //提出质疑人
                    $datas[$k]['create_user_role'] = empty($v['create_user_id']) ? '系统' : '';
                    if(!empty($v['create_user_id']) && isset($userArr[$v['create_user_id']])){
                        $datas[$k]['create_user_role'] = !empty($v['submit_role']) ? $userArr[$v['create_user_id']].'【'.$v['submit_role'].'】' : $userArr[$v['create_user_id']];
                    }
                    unset($datas[$k]['sign_id']);
                    unset($datas[$k]['create_user_id']);
                }
                unset($applyNoteDatas);
                unset($sigRoleUserArr);
                unset($sigUserTelArr);
                unset($roleNameArr);
            }



            $formatter = new Formatter();
            $formatter::format($datas, new LogicErrorFormatter());

            if($status == 'isReply' && !empty($datas)){
                foreach($datas as &$data){
                    $data['apply_note'] = '';
                    if(isset($data['reply']) && !empty($data['reply'])){
                        foreach($data['reply'] as $data_reply){
                            if($data_reply['is_reply'] == 1){
                                $data['apply_note'] = $data_reply['content'];
                            }
                        }
                    }
                }
            }
            //显示字段表结构
            $FormFiledData = [
                ["label" => "受试者","prop" => "patient_id",'width' => '260'],
                ["label" => "检查点","prop" => "check_name",'width' => '160'],
                ["label" => "表单名称","prop" => "form_name",'width' => '160'],
                ["label" => "质疑描述","prop" => "expression_note"],
            ];
            if($status == 'isReply'){//已回复 增加回复内容
                $FormFiledData[] = [
                    "label" => "回复内容",
                    "prop" => "apply_note",
                    'width' => '180'
                ];
            }
            $FormFiledData[] = [
                "label" => "提出质疑人",
                "prop" => "create_user_role",
                'width' => '180'
            ];


            //搜索表结构
            $serchFormFileData = [
                ["type" => "Input","label" => "筛选号","placeholder" => "请输入筛选号","prop" => "patient_number"],
                ["type" => "Input","label" => "质疑描述","placeholder" => "请输入“人工”或“系统”以查看对应类型的质疑信息/质疑描述","prop" => "error_message",'width'=>'410px'],
                ["type" => "Select","label" => "提出质疑人员","placeholder" => "请选择提出质疑人员",'multiple' => true,"prop" => "serch_user",'options'=>$select_users],
            ];
            unset($select_users);
            unset($searchItemSignatoryData);

            //提出质疑角色
            $serch_role[] = ['value'=> '0','label' => '无'];

            $roles = $this->LocalService()->realRole->fetchAll([
                'where'   => 'item_id=' . $fid,
                'columns' => ['value' => 'id', 'label' => 'role_name'],
                'order'   => ['id asc']
            ]);

            $serch_role = array_merge($serch_role,$roles);
            $serchFormFileData[] = [
                "type" => "Select",
                'label' => '提出质疑角色',
                'prop' => 'user_role',
                'multiple' => false,
                'options'=>$serch_role,
            ];

            if($status != ''){
                $serchFormFileData[] = [
                    "type" => "Input",
                    'label' => '质疑回复',
                    "placeholder" => "请输入质疑回复",
                    'prop' => 'apply_note',
                ];
            }

            return $this->RenderApiJson()->success($datas,'',['total'=>$total,'FormFileData'=>$FormFiledData,'SerchFormFileData'=>$serchFormFileData,'limit'=>$limit,'page'=>$page,'itemSignatoryData'=>$itemsignatoryData]);

        }else{
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR,'非法请求');
        }

    }

    public function errorQueriedCreateAction()
    {
        $data         = StringHelper::jsonDecode($this->params()->fromPost('data'));
        $post_keys1   = $data[0]['only_keys1'];
        $post_keys2   = $data[0]['only_keys2'];
        $redis        = Laminas::$serviceManager->redisExtend->getRedisInstance();
        $patientformcontent_id = $this->params()->fromPost('patientformcontent_id', 0);
        if(empty($patientformcontent_id)){
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数错误！！');
        }

        if(!empty($post_keys1) && !empty($post_keys2)){
            //有key1  只验证不销毁
            if(!$redis->exists($post_keys2)){
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '重复提交！');
            }
        }else{
            //无key1 验证key2并销毁
            if(!$redis->exists($post_keys2)){
                return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '重复提交！');
            }
            $redis->del($post_keys2);  //验证完销毁
        }

        foreach ($data as $k => $v) {
            $err = Laminas::$serviceManager->itemPatientFormLogicError->fetchOne([
                'where' => ['id' => $v['id']]
            ]);
            if ($v['platform'] == Laminas::$serviceManager->itemPatientFormLogicErrorQuery::PLATFORM_SDM) {

                Laminas::$serviceManager->itemPatientFormLogicErrorPointer->update(['is_reply' => 1], ['id' => $v['message_id']]);

                Laminas::$serviceManager->itemPatientFormLogicErrorLog->update(['is_reply' => 1], ['error_id' => $v['id']]);

                Laminas::$serviceManager->itemPatientFormLogicError->update(['is_queried' => 1, 'is_reply' => 1], ['id' => $v['id']]);
            }

            $is_error_ocr = stripos($v['content'], '识别有误') !== false;

            Laminas::$serviceManager->itemPatientFormLogicErrorQuery->save([
                'content' => $v['content'],
                'error_id' => $v['id'],
                'platform' => $v['platform'] ?: Laminas::$serviceManager->itemPatientFormLogicErrorQuery::PLATFORM_EDC,
                'is_reply' => 1,
                'pointer_id' => $v['message_id'],
                'is_auditor' => $v['is_auditor'] ?? 0,
                'item_id' => $v['item_id']
            ]);

            if($is_error_ocr) {
                Laminas::$serviceManager->itemPatientFormLogicError->update([
                    'is_report_special' => 1
                ], [
                    'id' => $v['id']
                ]);

                $changeId = !empty($err) ? $err['multi_id'] : '';
                $changeData = Laminas::$serviceManager->itemIdentificationresultchange->fetchOne([
                    'where' => ['id' => $changeId],
                    'column' => ['item_id','itemsig_id','patient_id','patient_form_id','item_checkname_id', 'is_annul']
                ]);

                if(!empty($changeData)) {
                    // 识别有误，则将未查的指标添加补充数据中
                    Laminas::$serviceManager->itemIdentificationresultchange->update([
                        'is_del' => 0,
                        'is_annul' => 1,
                        'lock_state' => 1
                    ], [
                        'id' => $changeId
                    ]);

                    // 添加作废的信息(如果之前就是作废的状态，就不在重复记录了)
                    if (!$changeData['is_annul']) {
                        $csae_data = $this->LocalService()->itemCsae->fetchOne(['where'=>'is_del = 0 and item_id = '.$changeData['item_id'].' and itemsig_id = '.$changeData['itemsig_id'].' and patient_id = '.$changeData['patient_id'].' and item_checkname_id = '.$changeData['item_checkname_id'].' and patient_form_id  = '.$changeData['patient_form_id']]);//获取csae信息
                        $csae_data = empty($csae_data) ? [] : $csae_data;
                        $save_destroy_data = [
                            'item_id' => $changeData['item_id'],
                            'itemsig_id' => $changeData['itemsig_id'],
                            'patient_id' => $changeData['patient_id'],
                            'patient_form_id' => $changeData['patient_form_id'],
                            'item_checkname_id' => $changeData['item_checkname_id'],
                            'destroy_remark' => '质疑系统自动作废指标',
                            'destroy_date' => time(),
                            'identificationresultchange_id' => $changeId,
                            'csae_data' => json_encode($csae_data)
                        ];
                        $this->LocalService()->itemIdentificationresultdestroy->save($save_destroy_data);
                    }
                }
            }

            //异步处理访视进度情况信息
            
            $form_content_arr = !is_null($err['multi_id']) && !empty($err['multi_id']) ? explode(',',$err['multi_id']) : [];
            if(isset($err['is_report']) && $err['is_report'] == 1){
                $form_content_id = Laminas::$serviceManager->patientFormContent->getOneFieldVal('id',[
                    'is_del' => 0,
                    'patient_id' => $this->params()->fromPost('patient_id', 0),
                    'checktime_id' => $this->params()->fromPost('checktime_id', 0),
                    'form_id' => $this->params()->fromPost('form_id', 0),
                ]);
                $form_content_arr = !empty($form_content_id) ? [$form_content_id] : [];
            }
            Laminas::$serviceManager->swTaskClient->send([
                'svName' => 'projectPatientworkbatch',
                'methodName' => 'multipleUpdateData',
                'params' => [
                    'item_id' => $this->params()->fromPost('item_id'),
                    'itemsig_id' => $this->params()->fromPost('itemsig_id'),
                    'patient_id' => $this->params()->fromPost('patient_id'),
                    'checktime_id' => $this->params()->fromPost('checktime_id'),
                    'form_id' => $this->params()->fromPost('form_id'),
                    'operate_type'=>$err['role'] == 1 ? 8 : 9,
                    'content_id'=>!empty($form_content_arr) ? $form_content_arr : [],
                    'user_id' => Laminas::$serviceManager->identity->getId()
                ]
            ]);
            unset($form_content_arr);

        }

        //异步处理工作质疑信息
        Laminas::$serviceManager->swTaskClient->send([
            'svName' => 'projectPatientwork',
            'methodName' => 'updatePatientworkData',
            'params' => [
                'item_id' => $this->params()->fromPost('item_id'),
                'itemsig_id' => $this->params()->fromPost('itemsig_id'),
                'patient_id' => $this->params()->fromPost('patient_id'),
                'checktime_id' => $this->params()->fromPost('checktime_id'),
                'form_id' => $this->params()->fromPost('form_id'),
                'user_id' => Laminas::$serviceManager->identity->getId(),
                'content_id' => $patientformcontent_id,
            ]
        ]);

        return $this->RenderApiJson()->Success();
    }
    
    public function errorClosedAction()
    {
        $id = $this->params()->fromPost('id');
        $this->validator->attach(
            [['id'], 'required']
        );

        if (!$this->validator->isValid()) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, $this->validator->getFirstErrorToString());
        }

        $err = Laminas::$serviceManager->itemPatientFormLogicError->fetchOne(['where' => ['id' => $id]]);
        $pointers = Laminas::$serviceManager->itemPatientFormLogicErrorPointer->fetchAll([
            'where' => ['error_id' => $id]
        ]);

        $callable = function ($id) {
            // 删除质疑
            Laminas::$serviceManager->itemPatientFormLogicError->update(['is_closed' => 1, 'is_del' => 1], ['id' => $id]);
            Laminas::$serviceManager->itemPatientFormLogicErrorQuery->update(['is_del' => 1], ['error_id' => $id]);
            Laminas::$serviceManager->itemPatientFormLogicErrorLog->update(['is_closed' => 1], ['error_id' => $id]);
            Laminas::$serviceManager->itemPatientFormLogicErrorPointer->update(['is_del' => 1], ['error_id' => $id]);
        };

        $callable($err['id']);

        return $this->RenderApiJson()->Success();
    }

    public function errorReplyAction()
    {
        $prop = $this->params()->fromPost('prop');
        if ($prop === 'reference_range_min') {
            $prop = 'range';
        }
        // 根据请求中传入的错误ID和属性，获取错误ID列表
        $errorId = Laminas::$serviceManager->itemPatientFormLogicErrorPointer->fetchAll([
            'where' => ['error_id' => explode(',', $this->params()->fromPost('error_id')), 'prop' => $prop]
        ]);

        // 获取提出的问题和回复
        $query = Laminas::$serviceManager->itemPatientFormLogicErrorQuery->fetchAll([
            'order' => ['error_id' => 'asc'],
            'columns' => ['create_user_id as create_user', 'content', 'create_time', 'platform', 'error_id', 'id'],
            'where' => ['error_id' => ArrayHelper::getColumn($errorId, 'error_id')]
        ]);

        $formatter = new Formatter();
        $formatter::format($query, new LogicErrorReplyFormatter());
        return $this->RenderApiJson()->Success($query);
    }

    public function setQueriedAction()
    {
        $model = new CheckLogicApplication();
        $model->setError($_POST);
        return $this->RenderApiJson()->Success();
    }

    /**
     * Notes : 逻辑核查-受试者列表
     * @return mixed
     * Author:唐伯虎不虎
     * Date:2024/11/19 15:09
     */
    public function geterrorpatientListAction()
    {
        $request = $this->getRequest();

        $questionType = $_POST['questionType'] ?: 0; //0质疑沟通    1 逻辑核查
        $status = $request->getPost('status');


        if ($_POST['sign_id']) {
            if($questionType == 1){
                $filter['error.sign_id'] = $_POST['sign_id'];
            }else{
                $filter['error.item_sign_id'] = $_POST['sign_id'];
                $filter['error.is_del'] = 0;
            }
        }

        if ($request->getPost('patient_number')) {
            $id = ArrayHelper::getColumn(Laminas::$serviceManager->patient->fetchAll([
                'columns' => ['id'],
                'where' => [new Like('patient_number', "%{$request->getPost('patient_number')}%")]
            ]), 'id');

            $filter['error.patient_id'] = $id;
        }


        if($questionType == 1){
            $sql = new Sql(Laminas::$app->getServiceManager()->get('edcDbAdapter'));
            $tableName = 'yikeen_item_patient_form_logic_error';
            $tableColumns = ['is_closed as status', 'patient_id'];
        }else {
            $sql = new Sql(Laminas::$app->getServiceManager()->get('dbAdapter'));
            $tableName = 'yikeen_item_question';
            $tableColumns = ['question_status as status', 'patient_id'];
        }

        $page = Laminas::$app->getRequest()->getPost('page', 1) - 1;
        $limit = Laminas::$app->getRequest()->getPost('limit', 10);

        $select = $sql->select()->columns($tableColumns)->from(['error' => $tableName])
            ->where(ArrayHelper::merge([
                'error.item_id' => $this->params()->fromPost('item_id'),
            ], $filter))->group('error.patient_id');

        $statement = $sql->prepareStatementForSqlObject($select);

        $resultSet = new ResultSet();

        $res = $resultSet->initialize($statement->execute())->toArray();

        $dataCount = count($res);

        if(!empty($res)){
            $patientDatas = $this->LocalService()->patient->fetchAll(['where'=> [
                'id' => StringHelper::toArray(array_unique(array_column($res,'patient_id')))
            ],'columns'=>['id','patient_order','patient_number']]);
            $patientDatas = ArrayHelper::index($patientDatas,'id');
            foreach ($res as $key=>$value){
                $res[$key]['patient_order'] = isset($patientDatas[$value['patient_id']]['patient_order']) && !empty($patientDatas[$value['patient_id']]['patient_order']) ? $patientDatas[$value['patient_id']]['patient_order'] : 0;
                $res[$key]['patient_number'] = isset($patientDatas[$value['patient_id']]['patient_number']) && !empty($patientDatas[$value['patient_id']]['patient_number']) ? $patientDatas[$value['patient_id']]['patient_number'] : 0;
            }
            array_multisort(
                array_column($res, 'patient_order'), SORT_ASC,
                $res
            );
            unset($patientDatas);

            //查询质疑信息【1 有 0 无】
            $noQuestionArr = [];
            $tableName = 'itemQuestion';
            $replyWhere = " and question_status = 0";
            if($questionType == 1){
                $tableName = 'itemPatientFormLogicError';
                $replyWhere = " and is_reply = 0 and is_closed = 0";
            }
            $replyStatusDatas = array_flip($this->LocalService()->$tableName->fetchCol('patient_id',"patient_id in (".implode(',',array_column($res,'patient_id')).") and is_del = 0 ".$replyWhere." group by patient_id"));
            unset($replyWhere);
            unset($tableName);
            foreach($res as $resKey=>&$v){
                $v['pendingReply'] = isset($replyStatusDatas[$v['patient_id']]) ? 1 : 0;
                if($v['pendingReply'] == 0){
                    $noQuestionArr[] = $v;
                    unset($res[$resKey]);
                }
            }
            unset($replyStatusDatas);
            $res = !empty($res) ? array_values($res) : [];
            if(!empty($noQuestionArr)){
                $res = !empty($res) ? ArrayUtils::merge($res,$noQuestionArr) : $noQuestionArr;
            }
            unset($noQuestionArr);
        }

        $pageData = array_slice($res, $limit * $page, $limit);
        unset($res);
        return $this->RenderApiJson()->Success($pageData, 'OK', ['total' => $dataCount]);
    }

    /**
     * Notes : 逻辑核查-受试者检查点列表
     * @return mixed
     * Author:唐伯虎不虎
     * Date:2024/11/19 15:09
     */
    public function geterrorchecktimeListAction()
    {
        $request = $this->getRequest();
        $questionType = $_POST['questionType'] ?: 0; //0质疑沟通    1 逻辑核查

        if ($_POST['sign_id']) {
            if($questionType == 1){
                $filter['error.sign_id'] = $_POST['sign_id'];
            }else{
                $filter['error.item_sign_id'] = $_POST['sign_id'];
            }
        }

        if ($_POST['patient_id']) {
            $filter['error.patient_id'] = $_POST['patient_id'];
        }

        if($questionType == 1){
            $sql = new Sql(Laminas::$app->getServiceManager()->get('edcDbAdapter'));
            $tableName = 'yikeen_item_patient_form_logic_error';
            $tableColumns = ['is_closed as status', 'patient_id','form_id'];
        }else {
            $sql = new Sql(Laminas::$app->getServiceManager()->get('dbAdapter'));
            $tableName = 'yikeen_item_question';
            $tableColumns = ['question_status as status', 'patient_id','form_id'];
        }

        $page = Laminas::$app->getRequest()->getPost('page', 1) - 1;
        $limit = Laminas::$app->getRequest()->getPost('limit', 10);

        $select = $sql->select()->columns($tableColumns)->from(['error' => $tableName])
            ->where(ArrayHelper::merge([
                'error.item_id' => $this->params()->fromPost('item_id'),
                'error.is_del' => 0,
            ], $filter))->group('error.form_id');

        $statement = $sql->prepareStatementForSqlObject($select);

        $resultSet = new ResultSet();

        $res = $resultSet->initialize($statement->execute())->toArray();

        $dataCount = count($res);

        if(!empty($res)){
            $formDatas = $this->LocalService()->itemForm->fetchAll(['where'=>"id in (".implode(',',array_unique(array_column($res,'form_id'))).")",'columns'=>['id','order','name']]);
            $formDatas = ArrayHelper::index($formDatas,'id');
            foreach ($res as $key=>$value){
                $res[$key]['order'] = isset($formDatas[$value['form_id']]['order']) && !empty($formDatas[$value['form_id']]['order']) ? $formDatas[$value['form_id']]['order'] : 0;
                $res[$key]['form_name'] = isset($formDatas[$value['form_id']]['name']) && !empty($formDatas[$value['form_id']]['name']) ? $formDatas[$value['form_id']]['name'] : 0;
            }
            array_multisort(
                array_column($res, 'order'), SORT_ASC,
                $res
            );
            unset($formDatas);

            //查询质疑信息【1 有 0 无】
            $noQuestionArr = [];
            $tableName = 'itemQuestion';
            $replyWhere = " and question_status = 0";
            if($questionType == 1){
                $tableName = 'itemPatientFormLogicError';
                $replyWhere = " and is_reply = 0 and is_closed = 0";
            }
            $replyStatusDatas = array_flip($this->LocalService()->$tableName->fetchCol('form_id',"form_id in (".implode(',',array_column($res,'form_id')).") and patient_id in (".implode(',',array_column($res,'patient_id')).") and is_del = 0 ".$replyWhere." group by patient_id,form_id"));
            unset($replyWhere);
            unset($tableName);
            foreach($res as $resKey=>&$v){
                $v['pendingReply'] = isset($replyStatusDatas[$v['form_id']]) ? 1 : 0;
                if($v['pendingReply'] == 0){
                    $noQuestionArr[] = $v;
                    unset($res[$resKey]);
                }
            }
            unset($replyStatusDatas);
            $res = !empty($res) ? array_values($res) : [];
            if(!empty($noQuestionArr)){
                $res = !empty($res) ? ArrayUtils::merge($res,$noQuestionArr) : $noQuestionArr;
            }
            unset($noQuestionArr);

        }
        $pageData = array_slice($res, $page, $limit);

        return $this->RenderApiJson()->Success($pageData, 'OK', ['total' => $dataCount]);
    }

    public function getlasterrorAction()
    {
        $id = $_POST['id'];
        $patient_id = $_POST['patient_id'];
        $form_id = $_POST['form_id'];
        $item_id = $_POST['item_id'];
        $nowRow = $_POST['rowCount'] ?: 0;
        $status = $_POST['status'];
        $where = '';
        if ($status == 'isReply') {
            $where = [
                'is_reply' => 1,
                'is_closed' => 0,
            ];
        } elseif ($status == 'isClosed') {
            $where = [
                'is_closed' => 1,
            ];
        } else {
            $where = [
                'is_closed' => 0,
                'is_reply' => 0,
            ];
        }

        $res = $this->LocalService()->itemPatientFormLogicError->fetchAll([
            'where'=> ArrayUtils::merge($where, [
                'is_del' => 0,
                'patient_id' => $patient_id,
                'form_id' => $form_id,
                'item_id' => $item_id,
            ]),
            'columns'=>['id','patient_id','checktime_id','form_id']
        ]);


        $questionStatusCount['pendingReply'] = 0;
        if(!empty($res)) {
            //受试者、检查点、表单
            $patient = implode(',', array_unique(array_column($res, 'patient_id')));

            $patientDatas = $this->LocalService()->patient->fetchCol('patient_order', "id in ($patient)");

            $checktime = implode(',', array_unique(array_column($res, 'checktime_id')));
            $checktimeInfos = $this->LocalService()->itemChecktime->fetchAll(['where' => [
                'id' => StringHelper::toArray($checktime)
            ], 'columns' => ['id', 'check_name', 'check_order']]);
            $checktimeInfos = ArrayHelper::index($checktimeInfos, 'id');

            $form = implode(',', array_unique(array_column($res, 'form_id')));
            $formOrderDatas = $this->LocalService()->itemForm->fetchCol('order', [
                'id' => StringHelper::toArray($form)
            ]);

            foreach ($res as $key => $value) {
                $res[$key]['checktime_oder'] = isset($checktimeInfos[$value['checktime_id']]['check_order']) && !empty($checktimeInfos[$value['checktime_id']]['check_order']) ? $checktimeInfos[$value['checktime_id']]['check_order'] : 0;
                $res[$key]['patient_order'] = isset($patientDatas[$value['patient_id']]) && !empty($patientDatas[$value['patient_id']]) ? $patientDatas[$value['patient_id']] : 0;
                $res[$key]['form_order'] = isset($formOrderDatas[$value['form_id']]) && !empty($formOrderDatas[$value['form_id']]) ? $formOrderDatas[$value['form_id']] : 0;
            }

            array_multisort(
                array_column($res, 'patient_order'), SORT_ASC,
                array_column($res, 'checktime_oder'), SORT_DESC,
                array_column($res, 'form_order'), SORT_DESC,
                $res
            );

            $lastIdDatas = array_slice($res, $nowRow, 1);

        }
        $lastId = 0;
        $rowCount = 0;
        if(!empty($lastIdDatas)){
            $lastId = $lastIdDatas[0]['id'];
            $rowCount = $nowRow + 1;
        }
        return $this->RenderApiJson()->Success(['lastId'=>intval($lastId),'rowCount'=>$rowCount]);
    }
}