<?php
/**
 *
 * @author：llbjj
 * @DateTime：2022/5/6 10:57
 * @Description：
 *
 */

namespace Application\Service\DB\Item;

use Application\Common\Exportenum;
use Application\Common\StatusCode;
use Application\Form\ExportModel;
use Application\Service\DB\Dictionary\FormField;
use Application\Service\DB\Dictionary\FormGroup;
use Application\Service\Extension\Helper\ArrayHelper;
use Application\Service\Extension\Helper\SDMHelper;
use Application\Service\Extension\Helper\StringHelper;
use Application\Service\Extension\Laminas;
use EasyWeChat\Kernel\Support\Str;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Predicate\Expression;
use Laminas\Db\Sql\Predicate\IsNull;
use Laminas\Db\Sql\Predicate\NotIn;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Where;
use Laminas\Stdlib\ArrayUtils;
use PhpOffice\PhpWord\PhpWord;
use Tightenco\Collect\Support\Arr;
use Vtiful\Kernel\Excel;
use Vtiful\Kernel\Format;


class Export extends \Application\Service\DB\AbstractDb
{
    const sigFormRolePrefix = 'RealRole';

    //受试者拓展属性数组
    private ?array $patientattrDatas = [];

    //项目名称
    private ?array $itemInfo = [];

    //中心数组
    private ?array $itemsigDatas = [];

    public $fieldType;

    public $field_options;

    private ?int $hide_type = 0;

    private $randomAlias;

    public function __construct($dbAdapter, ContainerInterface $container)
    {
        $this->tableName = 'yikeen_item_export';
        parent::__construct($dbAdapter, $container);
    }

    /**
     * Notes :受试者状态回显
     * @param $patient_status
     * @return string
     * Author:lwl
     * Date:2022/8/3 14:11
     */
    public function getpatientStatus($export_type, $patient_status)
    {
        if ($patient_status) {
            $patientStatus = explode(',', $patient_status);
            $status = [];
            //【0终止  1脱落  2失败 3 完成】',

            if (in_array(9, $patientStatus)) {
                $status[] = '进行中';
            }
            if (in_array(4, $patientStatus)) {
                $status[] = '中止';
            }
            if (in_array(1, $patientStatus)) {
                $status[] = '脱落';
            }
            if (in_array(2, $patientStatus)) {
                $status[] = '筛败';
            }
            if (in_array(3, $patientStatus)) {
                $status[] = '完成';
            }
            if (in_array(10, $patientStatus)) {
                $status[] = '--';
            }
            return implode(',', $status);
        } else {
            if ($export_type == 1) {
                return 'All';
            } else {
                return '--';
            }
        }
    }

    /**
     * Notes :返回项目检查点
     * @param $item_id
     * @return array
     * Author:lwl
     * Date:2022/8/3 14:08
     */
    public function getItemchecktime($item_id)
    {
        $whereArr['where'] = [
            'item_id' => $item_id,
            'is_del' => [0, 9],
        ];
        $whereArr['columns'] = ['id', 'check_name', 'stage_id', 'order' => 'check_order', 'is_del', 'random_id','patientchecktime_id','check_order','is_isolate'];
        $whereArr['order'] = 'check_order'; 
        $data = $this->LocalService()->itemChecktime->fetchAll($whereArr);
        $checktimeDatas = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $checktimeDatas[$v['id']] = $v;
            }
        }
        return $checktimeDatas;
    }

    /**
     * Notes :返回项目阶段
     * @param $item_id
     * @return array
     * Author:lwl
     * Date:2022/8/3 14:09
     */
    public function getItemstage($item_id)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $whereArr['columns'] = ['id', 'stage_name', 'order' => 'stage_order'];
        $whereArr['order'] = 'stage_order';
        $data = $this->LocalService()->itemResearchstage->fetchAll($whereArr);
        $stageDatas = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $stageDatas[$v['id']] = $v;
            }
        }
        return $stageDatas;
    }

    /**
     * Notes :返回项目检查项以及分类
     * @param int $item_id
     * @param int $category_id
     * @return mixed
     * Author:lwl
     * Date:2022/8/3 14:10
     */
    public function getItemcheckname($item_id, $category_id = 0)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($category_id != 0) {
            $whereArr['where']['category_id'] = StringHelper::toArray($category_id);
        }
        $whereArr['columns'] = ['id', 'category_id', 'checkname_id', 'name', 'show_name', 'variable', 'unit', 'max_val', 'min_val', 'check_type', 'max_symbol', 'min_symbol'];
        $whereArr['order'] = ['checkname_order', 'id'];
        $data = $this->LocalService()->itemCheckname->fetchAll($whereArr);

        if (empty($data)) {
            return [];
        }
        $checknameDatas = [];
        $categoryidArr = [];

        //检查项
        foreach ($data as $k => $v) {
            $categoryidArr[] = $v['category_id'];
            $checknameDatas[$v['category_id']][] = $v;
        }

        //检查项分类
        $categorywhereArr['where'] = [
            'is_del' => 0,
            'id' => array_unique($categoryidArr)
        ];
        $categorywhereArr['columns'] = ['id', 'category_name', 'category_variable', 'report_type'];

        $categoryData = $this->LocalService()->dictionaryCheckcategory->fetchAll($categorywhereArr);
        $categoryDatas = [];
        foreach ($categoryData as $k => $v) {
            $categoryDatas[$v['id']] = $v;
        }
        $back['checknameDatas'] = $checknameDatas;
        $back['categoryDatas'] = $categoryDatas;

        return $back;
    }

    /**
     * Notes : 导出--筛选受试者
     * @param int $item_id
     * @param int $itemsig_id
     * @param int $patient_id
     * @param int $patient_status
     * @return array
     * Author:lwl
     * Date:2022/8/3 14:10
     */
    public function getItempatinet(int $item_id, $itemsig_id = '', string $patient_id = '', $patient_status,$columns = [])
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($itemsig_id != '') $whereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_id);
        if ($patient_id != '' && $patient_id != 0) $whereArr['where']['id'] = StringHelper::toArray($patient_id);
        if ($patient_status != 10 || strlen($patient_status) > 2) {
            $whereArr['where']['patient_status'] = StringHelper::toArray($patient_status);
        }
        if(!empty($columns)){
            $whereArr['columns'] = $columns;
        }else{
            $whereArr['columns'] = ['id', 'itemsig_id', 'patient_name', 'patient_number', 'random_number', 'randgroup_id', 'random_id', 'order' => 'patient_order', 'patient_content', 'patient_status','joining_date'];
        }
        $whereArr['order'] = 'patient_order';
        $data = $this->LocalService()->patient->fetchAll($whereArr);
        $patientDatas = [];
        //检查项
        foreach ($data as $k => $v) {
            $patientDatas[$v['itemsig_id']][$v['id']] = $v;
        }
        return $patientDatas;
    }

    /**
     * Notes : 导出--筛选受试者
     * @param int $item_id
     * @param int $itemsig_id
     * @param int $patient_id
     * @param int $patient_status
     * @return array
     * Author:lwl
     * Date:2022/8/3 14:10
     */
    public function getItempatinetdata(int $item_id, $itemsig_id = '', string $patient_id = '', $patient_status)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];

        if ($itemsig_id != '') $whereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_id);
        if ($patient_id != '' && $patient_id != 0) $whereArr['where']['id'] = StringHelper::toArray($patient_id);
        if ($patient_status != 10 || strlen($patient_status) > 2) {
            $whereArr['where']['patient_status'] = StringHelper::toArray($patient_status);
        }

        $whereArr['columns'] = ['id','itemsig_id', 'patient_name', 'patient_number', 'patient_status','patient_order'];
        $whereArr['order'] = 'patient_order';
        $data = $this->LocalService()->patient->fetchAll($whereArr);
        $patientDatas = [];
        //检查项
        foreach ($data as $k => $v) {
            $patientDatas[$v['id']] = $v;
        }
        return $patientDatas;
    }

    /**
     * Notes : 获取项目表单
     * @param $item_id
     * @param $form_id
     * @return array
     * Author:唐伯虎不虎
     * Date:2022/9/19 14:36
     */
    public function getform($item_id, $form_id)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($form_id != 0) $whereArr['where']['id'] = StringHelper::toArray($form_id);
        $whereArr['columns'] = ['id', 'name', 'type', 'code', 'rdg_type', 'group_id', 'checklist_id', 'var_name','order','is_using_score'];
        $whereArr['order'] = 'order';
        $data = $this->LocalService()->itemForm->fetchAll($whereArr);

        $content = $this->LocalService()->itemCheckcontent->fetchCol('form_id',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        $content = array_flip(array_unique($content));

        $formdata = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                if(isset($content[$v['id']]) || $v['group_id'] == 3 || $v['group_id'] == 5 || $v['group_id'] == 1){
                    $formdata[$v['id']] = $v;
                }
            }
        }
        return $formdata;
    }

    /**
     * 受试者检查点
     */
    public function getpatientchecktime($item_id,$patient_ids=0,$checktime_id=0)
    {

        $where['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($patient_ids != 0) $where['where']['patient_id'] = StringHelper::toArray($patient_ids);
        $where['columns'] = ['id','patient_id','checktime_id','plan_start_date','plan_end_date'];
        $patientchecktimeDatas = $this->LocalService()->itemPatientchecktime->fetchAll($where);

        $resultData = [];
        if(!empty($patientchecktimeDatas)){
            $time = time();
            foreach($patientchecktimeDatas as $k=>$v){
                if((int)$v['plan_start_date'] > $time) continue;
                $resultData[$v['patient_id'].'-'.$v['checktime_id']] = $v;
            }
        }
        return $resultData;
    }

    /**
     * Notes : 受试者填写数据
     * @param $item_id
     * @param $patient_ids
     * @param $form_ids
     * @return array
     * Author:唐伯虎不虎
     * Date:2022/9/20 16:28
     */
    public function getpatientform($item_id, $patient_ids, $form_ids, $itemsig_ids, $create_id = '',$is_complete = 1,$is_yc=0)
    {
        $formContentWhere = new Where();
        $formContentWhere->equalTo('is_del',0)
            ->equalTo('item_id',$item_id);

        if ($patient_ids != 0) $formContentWhere->in('patient_id',StringHelper::toArray($patient_ids));
        if ($form_ids != 0) $formContentWhere->in('form_id',StringHelper::toArray($form_ids));
        if ($itemsig_ids != 0) $formContentWhere->in('itemsig_id',StringHelper::toArray($itemsig_ids));
        if ($create_id != 0) $formContentWhere->in('create_user_id',StringHelper::toArray($create_id));

        if($is_yc == 99){
            $formContentWhere->nest()
                ->equalTo('is_complete',0)
                ->or
                    ->nest()
                    ->equalTo('is_complete',1)
                    ->equalTo('is_yc',0)
                    ->unnest()
                ->unnest();
        }else{
            $formContentWhere->equalTo('is_complete',$is_complete);
            if($is_yc == 9) $formContentWhere->equalTo('is_yc',0);
        }
        $patientformwhereArr['where'] = $formContentWhere;
        $patientformwhereArr['columns'] = ['id', 'patient_id', 'form_id', 'checktime_id', 'data', 'itemsig_id', 'is_yc', 'create_user_id','is_complete'];
        $patientformcontent = $this->LocalService()->patientFormContent->fetchAll($patientformwhereArr);

        $formDatas = $this->getform($item_id, $form_ids);
        if(empty($form_ids)){
            $form_ids = implode(',',array_column($formDatas,'id'));
        }

        $FormRelationwhere['where'] = [
            'is_del' => 0,
            'form_id' => array_column($formDatas,'id'),
        ];
        $FormRelationwhere['columns'] = ['form_id','relation_form_id'];
        $FormRelationDatas=$this->LocalService()->itemFormRelation->fetchAll($FormRelationwhere);

        $relation = [];
        foreach($FormRelationDatas as $k=>$v){
            $relation[$v['form_id']] = $v['form_id'];
        }
        unset($FormRelationDatas);
        $group4_relationContent = [];
        $activeIndex = [];

        $patientformwhereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'is_inactive' => 0,
        ];
        if ($form_ids != 0) $patientformwhereArr['where']['form_id'] = StringHelper::toArray($form_ids);
        if ($patient_ids != 0) $patientformwhereArr['where']['patient_id'] = StringHelper::toArray($patient_ids);
        if ($itemsig_ids != 0) $patientformwhereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_ids);
        if ($create_id != 0) $patientformwhereArr['where']['create_user_id'] = StringHelper::toArray($create_id);
        $patientformwhereArr['columns'] = ['id', 'patient_id', 'form_id', 'checktime_id'];
        $patientform = $this->LocalService()->patientForm->fetchAll($patientformwhereArr);
        foreach($patientform as $kk=>$vv){
            $activeIndex[$vv['patient_id'].'-'.$vv['checktime_id'].'-'.$vv['form_id']] = 1;
            if(in_array($vv['form_id'],$relation)){
                if(!in_array($vv['checktime_id'],$group4_relationContent[$vv['patient_id'].'-'.$vv['form_id']])){
                    $group4_relationContent[$vv['patient_id'].'-'.$vv['form_id']][] = $vv['checktime_id'];
                }
            }
        }
        unset($patientform);
        $patientformDatas = [];
        if (!empty($patientformcontent)) {
            foreach ($patientformcontent as $k => $v) {
                if(!isset($activeIndex[$v['patient_id'].'-'.$v['checktime_id'].'-'.$v['form_id']])) continue;
                //没到的检查点跳过
                if($formDatas[$v['form_id']]['group_id'] == 4 && isset($relation[$v['form_id']])){
                    //如果是关联表单并且是贯穿全程表单
                    foreach($group4_relationContent[$vv['patient_id'].'-'.$vv['form_id']] as $relationK => $relationV){
                        $v['checktime_id'] = $relationV;
                        $v['id'] += $relationK+$vv['patient_id'];
                        $patientformDatas[$v['form_id']][] = $v;
                    }
                }else{
                    $patientformDatas[$v['form_id']][] = $v;
                }
            }
        }
        unset($patientformcontent);
        return $patientformDatas;
    }

    /**
     * Notes : 受试者AE
     *
     * @param $item_id
     * @param $patient_ids
     * @return array
     * Author:唐伯虎不虎
     * Date:2022/9/27 10:48
     */
    public function getpatientAeform($item_id, $patient_ids, $itemsig_ids)
    {
        $patientformwhereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($patient_ids != 0) $patientformwhereArr['where']['patient_id'] = StringHelper::toArray($patient_ids);
        if ($itemsig_ids != 0) $patientformwhereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_ids);
        $patientformwhereArr['columns'] = ['id', 'patient_id', 'form_id', 'data', 'itemsig_id', 'csae_id','branch'];
        $patientformcontent = $this->LocalService()->itemPatientAeContent->fetchAll($patientformwhereArr);
        if (!empty($patientformcontent)) {
            $patientID = array_unique(array_column($patientformcontent, 'patient_id'));
            foreach ($patientID as $k => $v) {
                if (empty($v)) {
                    unset($patientID[$k]);
                }
            }

            $csaerelationwhereArr['columns'] = ['id', 'patient_id', 'content_id'];
            $csaerelationwhereArr['where'] = [
                'is_del' => 0,
                'patient_id' => $patientID
            ];
            $csaerelationDatas = $this->LocalService()->itemCsaeRelation->fetchAll($csaerelationwhereArr);
            $relationData = [];
            foreach ($csaerelationDatas as $k => $v) {
                $relationData[$v['content_id']] = $v;
            }

            $patientformDatas = [];
            if (!empty($patientformcontent)) {

                foreach ($patientformcontent as $key => $value) {
                    if (isset($relationData[$value['id']])) {
                        $patientformDatas[$value['form_id']][$value['id']] = $value;
                    }
                }
            }
            return $patientformDatas;
        }
        return [];
    }

    //递归处理数据
    public function handledata($result, $children)
    {
        $relations = [];
        foreach ($children['children'] as $kk => $vv) {
            if (isset($vv['relation_information'])) {
                foreach ($vv['relation_information'] as $ks => $vs) {
                    if ($vs == 0) continue;
                    $relations[] = $vs;
                    $relations[] = $this->handledata($result, $result[$vs]);
                }
            }
        }
        return implode(',', $relations);
    }

    public function getParentKey($arr, $key, $id)
    {
        $relations = [];
        if (!empty($arr[$key])) {
            if (is_array($arr[$key])) {
                foreach ($arr[$key] as $k => $v) {
                    if (!empty($id)) {
                        if ($v == $id) {
                            $relations[] = $v;
                        }
                    } else {
                        $relations[] = $v;
                    }
                    $relations[] = $this->getParentKey($arr, $v, 0);
                }
            } else {
                $relations[] = $arr[$key];
                $relations[] = $this->getParentKey($arr, $arr[$key]);
            }
        }
        $result = rtrim(implode(',', $relations), ',');
        $result = ltrim($result, ',');
        return $result;
    }

    /**
     * 获取共享图片
     */
    public function getshareImg($item_id)
    {
        //获取项目下共享图片的表单
        $form = $this->LocalService()->itemForm->fetchAll([
            'where'=> [
                'item_id' => $item_id,
                'is_del' => 0,
                new Operator('gco_pool', Operator::OP_NE, '')
            ],
            'columns'=>['id','gco_pool']
        ]);
        if(empty($form)) return [];

        $formID = array_column($form,'id');

        $field = $this->LocalService()->itemFormField->fetchCol('id',[
            'is_del' => 0,
            'form_id' => $formID,
            'type' => FormField::FORM_FIELD_TYPE_UPLOAD_SHARE_IMAGE,
        ]);

        $gcoPool = [];
        foreach($form as $k=>$v){
            $gcoPool[$v['gco_pool']][] = $v['id'];
        }

        $form_gcopool = ArrayHelper::index($form,'id');

        $contentImg = $this->LocalService()->patientFormContentImg->fetchAll([
            'where'=> [
                'is_del' => 0,
                'item_id' => $item_id,
                'form_id' => $formID,
            ],
            'columns'=>['patient_id','checktime_id','form_id','field_id'],
            'group'=>['patient_id','checktime_id','form_id'],
            'order'=>['patient_id','checktime_id','form_id'],
        ]);
        if(!empty($contentImg)){
            $merge = [];
            //受试者、检查点、分组
            foreach($contentImg as $k=>$v){
                $merge[$v['patient_id'].'-'.$v['checktime_id'].'-'.$form_gcopool[$v['form_id']]['gco_pool']] = 1;
            }
        }
        return [$form_gcopool,$merge];
    }

    /**
     * Notes : 获取项目表单父级字段
     * @param $item_id
     * @return array
     * Author:唐伯虎不虎
     * Date:2022/9/21 9:07
     */
    public function getformrules($item_id, $form_ids)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            [
                'or' => [
                    'parent' => 0,
                    new IsNull('parent'),
                ]
            ]
        ];
        if ($form_ids != 0) $whereArr['where']['form_id'] = StringHelper::toArray($form_ids);
        $whereArr['columns'] = ['id', 'type'];
        $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);

        foreach ($formfieldData as $k => $v) {
            $this->fieldType[$v['id']] = $v;
        }

        $formwhereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($form_ids != 0) $formwhereArr['where']['id'] = StringHelper::toArray($form_ids);
        $formwhereArr['columns'] = ['id'];
        $formwhereArr['order'] = 'order';
        //表单ID
        $formDatas = $this->LocalService()->itemForm->fetchAll($formwhereArr);
        $data = [];

        $item_fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称
        $blind_method = $this->LocalService()->itemInfo->getOneFieldVal('blind_method', [
            'is_del' => 0,
            'id' => $item_fid,
        ]);//获取项目名称

        $hidefieldData = [];
        if(empty($this->hide_type)){  //0 不导出隐私字段 1 导出
            $whereArr['where']['is_hide'] = 1;  //查询隐私字段
            $hidefieldData = $this->LocalService()->itemFormField->fetchCol('id',$whereArr['where']);
        }

        //循环处理表单version
        foreach ($formDatas as $key => $value) {
            $rule = $this->LocalService()->itemForm->setPreviewScenario('previewShareFormUnlock')->getPreviewConfig($value['id']);

            /*
             * 常規識別表單存在共享圖片的情況---适配
             * */
            foreach ($rule['form'] as $k => $v) {

                //不导出隐私字段
                if(empty($this->hide_type) && in_array($v['field_id'],$hidefieldData)){
                    continue;
                }

                if (in_array($this->fieldType[$v['prop']]['type'], [17, 18])) continue;
                if(count($v) == 2 || isset($this->fieldType['field_id']['type']) && $this->fieldType['field_id']['type'] == 19){
                    $temporaryarr['is_share'] = 1;
                    $data[$value['id']]['var_name'][] = '';
                    $data[$value['id']]['name'][] = '共享图片';
                }else{
                    $data[$value['id']]['var_name'][] = $v['var_name'];
                    $data[$value['id']]['name'][] = $v['label'];
                    $temporaryarr['is_share'] = 0;
                }

                $temporaryarr['id'] = $v['prop'];
                $temporaryarr['type'] = $this->fieldType[$v['prop']]['type'];
                $temporaryarr['patents'] = $v['prop'];
                $temporaryarr['var_name'] = $v['var_name'];

                if ($v['var_name'] == 'RANDOM_GROUP_SYSTEM' || $v['var_name'] == 'RANGCA' || $v['var_name'] == 'RANDOM_GROUP_CUSTOM' || $v['var_name'] == 'RANGC') {
                    if ($blind_method == 0) {
                        $data[$value['id']]['var_name'][] = 'GRPID';
                        $data[$value['id']]['name'][] = '方案分组';
                    }
                    $data[$value['id']]['var_name'][] = 'RANDID';
//                    $data[$value['id']]['name'][] = '随机号';
                    $data[$value['id']]['name'][] = $this->randomAlias;
                }

                $data[$value['id']]['data'][] = $temporaryarr;
                if (isset($rule[$v['prop']]) && $v['var_name'] != 'RANGC' && $v['var_name'] != 'RANDOM_GROUP_CUSTOM') {
                    //单选/多选 有两层
                    $arr = $this->handlefieldrules($rule, $v['prop'], $blind_method);
                    $data[$value['id']]['var_name'] = array_merge($data[$value['id']]['var_name'], $arr['var_name']);
                    $data[$value['id']]['name'] = array_merge($data[$value['id']]['name'], $arr['name']);
                    $data[$value['id']]['data'] = array_merge($data[$value['id']]['data'], $arr['data']);
                }
            }
        }
        return $data;
    }

    public function handlefieldrules($rules, $id, $blind_method)
    {
        $data = [];
        foreach ($rules[$id] as $childK => $childV) {
            foreach ($childV as $childfieldK => $childfieldV) {
                if (isset($this->fieldType[$childfieldV['prop']]['type']) && in_array($this->fieldType[$childfieldV['prop']]['type'], [17, 18])) continue;
                $data['var_name'][] = $childfieldV['var_name'];
                if ($childfieldV['var_name'] == 'RANDOM_GROUP_SYSTEM' || $childfieldV['var_name'] == 'RANGCA' ||$childfieldV['var_name'] == 'RANDOM_GROUP_CUSTOM' || $childfieldV == 'RANGC') {
                    if ($blind_method == 0) {
                        $data['var_name'][] = 'GRPID';
                        $data['name'][] = '方案分组';
                    }
                    $data['var_name'][] = 'RANDID';
//                    $data['name'][] = '随机号';
                    $data['name'][] = $this->randomAlias;
                }

                $temporaryarr['id'] = explode("-", $childfieldV['prop'])[0];
                $temporaryarr['type'] = $this->fieldType[$temporaryarr['id']]['type'];
                $temporaryarr['patents'] = $childfieldV['prop'];
                $temporaryarr['var_name'] = $childfieldV['var_name'];
                //选项类型字段需要拼接选项内容、选项值
                if ($temporaryarr['type'] == 10 || $temporaryarr['type'] == 11 || $temporaryarr['type'] == 12) {
                    //处理选项值拼接
                    $option_coutent = '';
                    if (isset($childfieldV['radios'])) {
                        foreach ($childfieldV['radios'] as $optionK => $optionV) {
                            $option_coutent .= '【' . $optionV['value'] . '】' . $optionV['label'] . ';';
                        }
                    }
                    if (isset($childfieldV['checkboxs'])) {
                        foreach ($childfieldV['checkboxs'] as $optionK => $optionV) {
                            $option_coutent .= '【' . $optionV['value'] . '】' . $optionV['label'] . ';';
                        }
                    }

                    $childfieldV['label'] .= $option_coutent;
                }

                $data['name'][] = $childfieldV['label'];


                $data['data'][] = $temporaryarr;
                if (isset($rules[$childfieldV['prop']])) {
                    //单选/多选 有两层
                    $arr = $this->handlefieldrules($rules, $childfieldV['prop'], $blind_method);
                    $data['var_name'] = array_merge($data['var_name'], $arr['var_name']);
                    $data['name'] = array_merge($data['name'], $arr['name']);
                    $data['data'] = array_merge($data['data'], $arr['data']);
                }
            }
        }
        return $data;
    }

    //导出excel模板，多选、单选、下拉字段需要带上选项值
    public function _getexcelmodelformrules($item_id, $form_ids)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            [
                'or' => [
                    'parent' => 0,
                    new IsNull('parent'),
                ]
            ]
        ];
        if ($form_ids != 0) $whereArr['where']['form_id'] = StringHelper::toArray($form_ids);
        $whereArr['columns'] = ['id', 'type'];
        $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);

        foreach ($formfieldData as $k => $v) {
            $this->fieldType[$v['id']] = $v;
        }

        $formwhereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if ($form_ids != 0) $formwhereArr['where']['id'] = StringHelper::toArray($form_ids);
        $formwhereArr['columns'] = ['id'];
        $formwhereArr['order'] = 'order';
        //表单ID
        $formDatas = $this->LocalService()->itemForm->fetchAll($formwhereArr);

        $data = [];

        $item_fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称
        $blind_method = $this->LocalService()->itemInfo->getOneFieldVal('blind_method', [
            'is_del' => 0,
            'id' => $item_fid,
        ]);//获取项目名称

        //循环处理表单version
        foreach ($formDatas as $key => $value) {
            $rule = $this->LocalService()->itemForm->getPreviewConfig($value['id']);
            foreach ($rule['form'] as $k => $v) {
                $data[$value['id']]['var_name'][] = $v['var_name'];
                $temporaryarr['id'] = $v['prop'];
                $temporaryarr['type'] = $this->fieldType[$v['prop']]['type'];
                $temporaryarr['patents'] = $v['prop'];
                $temporaryarr['var_name'] = $v['var_name'];

                //选项类型字段需要拼接选项内容、选项值
                if ($temporaryarr['type'] == 10 || $temporaryarr['type'] == 11 || $temporaryarr['type'] == 12) {
                    //处理选项值拼接
                    $option_coutent = '';
                    if (isset($v['radios'])) {
                        foreach ($v['radios'] as $optionK => $optionV) {
                            $option_coutent .= '【' . $optionV['value'] . '】' . $optionV['label'] . ';';
                        }
                    }
                    if (isset($v['checkboxs'])) {
                        foreach ($v['checkboxs'] as $optionK => $optionV) {
                            $option_coutent .= '【' . $optionV['value'] . '】' . $optionV['label'] . ';';
                        }
                    }

                    $v['label'] .= $option_coutent;
                }
                $data[$value['id']]['name'][] = $v['label'];


                if ($v['var_name'] == 'RANDOM_GROUP_SYSTEM' || $v['var_name'] == 'RANGCA') {
                    if ($blind_method == 0) {
                        $data[$value['id']]['var_name'][] = 'GRPID';
                        $data[$value['id']]['name'][] = '方案分组';
                    }
                    $data[$value['id']]['var_name'][] = 'RANDID';
//                    $data[$value['id']]['name'][] = '随机号';
                    $data[$value['id']]['name'][] = $this->randomAlias;
                }
                if($v['var_name'] == 'RANDOM_GROUP_CUSTOM' || $v['var_name'] == 'RANGC'){
                    if ($blind_method == 0) {
                        $data[$value['id']]['var_name'][] = 'GRPID';
                        $data[$value['id']]['name'][] = '方案分组';
                    }
                }

                $data[$value['id']]['data'][] = $temporaryarr;
                if (isset($rule[$v['prop']])) {
                    //单选/多选 有两层
                    $arr = $this->handlefieldrules($rule, $v['prop'], $blind_method);
                    $data[$value['id']]['var_name'] = array_merge($data[$value['id']]['var_name'], $arr['var_name']);
                    $data[$value['id']]['name'] = array_merge($data[$value['id']]['name'], $arr['name']);
                    $data[$value['id']]['data'] = array_merge($data[$value['id']]['data'], $arr['data']);
                }
            }
        }
        return $data;
    }

    public function _getexcelmodelhandlefieldrules($rules, $id)
    {
        $data = [];
        foreach ($rules[$id] as $childK => $childV) {
            foreach ($childV as $childfieldK => $childfieldV) {
                $data['var_name'][] = $childfieldV['var_name'];

                $temporaryarr['id'] = explode("-", $childfieldV['prop'])[0];

                $temporaryarr['type'] = $this->fieldType[$temporaryarr['id']]['type'];
                $temporaryarr['patents'] = $childfieldV['prop'];
                $temporaryarr['var_name'] = $childfieldV['var_name'];
                $data['data'][] = $temporaryarr;

                if ($temporaryarr['type'] == 10 || $temporaryarr['type'] == 11 || $temporaryarr['type'] == 12) {
                    //处理选项值拼接
                    $option_coutent = '';
                    if (isset($childfieldV['radios'])) {
                        foreach ($childfieldV['radios'] as $optionK => $optionV) {
                            $option_coutent .= '【' . $optionV['value'] . '】' . $optionV['label'] . ';';
                        }
                    }
                    if (isset($childfieldV['checkboxs'])) {
                        foreach ($childfieldV['checkboxs'] as $optionK => $optionV) {
                            $option_coutent .= '【' . $optionV['value'] . '】' . $optionV['label'] . ';';
                        }
                    }

                    $childfieldV['label'] .= $option_coutent;
                }
                $data['name'][] = $childfieldV['label'];

                if ($childfieldV['var_name'] == 'RANDOM_GROUP_SYSTEM' || $childfieldV['var_name'] == 'RANGCA' || $childfieldV['var_name'] == 'RANDOM_GROUP_CUSTOM' || $childfieldV['var_name'] == 'RANGC') {
                    $data['var_name'][] = 'GRPID';
                    $data['var_name'][] = 'RANDID';
                    $data['name'][] = '方案分组';
//                    $data['name'][] = '随机号';
                    $data['name'][] = $this->randomAlias;
                }

                if (isset($rules[$childfieldV['prop']])) {
                    //单选/多选 有两层
                    $arr = $this->handlefieldrules($rules, $childfieldV['prop']);
                    $data['var_name'] = array_merge($data['var_name'], $arr['var_name']);
                    $data['name'] = array_merge($data['name'], $arr['name']);
                    $data['data'] = array_merge($data['data'], $arr['data']);
                }
            }
        }
        return $data;
    }

    /**
     * Notes : 获取表单选项
     * @param $item_id
     * @param $form_ids
     * @return array
     * Author:唐伯虎不虎
     * Date:2022/9/21 9:11
     */
    public function getformoptions($item_id, $form_ids, $type = 0)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            [
                'or' => [
                    'type' => 0,
                    new IsNull('type'),
                ]
            ]
        ];
        if ($form_ids != 0) $whereArr['where']['form_id'] = StringHelper::toArray($form_ids);
        $whereArr['columns'] = ['id', 'name', 'parent', 'var_name'];
        $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);
        if ($form_ids == 0) {
            $formDatas = $this->LocalService()->itemForm->fetchCol('id', [
                'is_del' => 0,
                'item_id' => $item_id,
            ]);
            if (!empty($formDatas)) {
                $form_ids = implode(',', $formDatas);
            }
        }

        $radiowhereArr['where']['form_id'] = StringHelper::toArray($form_ids);
        $radiowhereArr['columns'] = ['id', 'field_id', 'value'];
        $radioDatas = $this->LocalService()->itemFormFieldRadio->fetchAll($radiowhereArr);
        $radio = [];
        foreach ($radioDatas as $k => $v) {
            $radio[$v['field_id']] = $v['value'];
        }

        $backArr = [];
        foreach ($formfieldData as $k => $v) {
            if ($type == 1) {
                $backArr[$v['parent']][$radio[$v['id']]] = $v;
            } else {
                $backArr[$v['parent']][$radio[$v['id']]] = $v['name'];
            }
        }
        return $backArr;
    }

    //试验总结类数据查询
    public function getsummaryData($item_id, $itemsig_ids)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'leave_type' => [1, 2, 3, 4]
        ];
        if ($itemsig_ids != 0) $whereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_ids);
        $whereArr['columns'] = ['id', 'item_id', 'patient_id', 'checktime_id', 'itemsig_id', 'leave_type', 'leave_date', 'stage_remark'];
        $data = $this->LocalService()->itemPatientchecktime->fetchAll($whereArr);
        return $data;
    }

    /**
     * Notes : 获取非AE数据
     * @param $item_id
     * @param $itemsig_ids
     * @param $patient_ids
     * @return array|\phpDocumentor\Reflection\Types\Mixed
     */
    public function getnotAe($item_id, $itemsig_ids, $patient_ids)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'ae_type' => [1,2,3,4]
        ];
        if ($itemsig_ids != 0) $whereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_ids);
        if ($patient_ids != 0) $whereArr['where']['patient_id'] = StringHelper::toArray($patient_ids);
        $whereArr['columns'] = ['id', 'item_id', 'patient_id', 'checktime_id', 'itemsig_id', 'ae_type', 'item_name', 'ae_remarks'];
        $data = $this->LocalService()->itemCsae->fetchAll($whereArr);
        return $data;
    }

    /**
     * Notes : 获取检查项AE数据
     * @param $item_id
     * @param $itemsig_ids
     * @param $patient_ids
     * @return array|\phpDocumentor\Reflection\Types\Mixed
     * Author:唐伯虎不虎
     */
    public function getchecknametAe($item_id, $itemsig_ids, $patient_ids)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'ae_type' => [5, 6]
        ];
        if ($itemsig_ids != 0) $whereArr['where']['itemsig_id'] = StringHelper::toArray($itemsig_ids);
        if ($patient_ids != 0) $whereArr['where']['patient_id'] = StringHelper::toArray($patient_ids);
        $whereArr['columns'] = ['id', 'item_id', 'patient_id', 'checktime_id', 'itemsig_id', 'patient_form_id', 'ae_type', 'item_name', 'relation_ae_id'];
        $data = $this->LocalService()->itemCsae->fetchAll($whereArr);
        return ArrayHelper::index($data,'id');
    }

    /**
     * Notes : 非AE状态
     * @param $type
     * @return string
     * Author:唐伯虎不虎
     */
    public function getarType($type)
    {
        if ($type == 1) {
            return '非AE与研究疾病有关';
        } elseif ($type == 2) {
            return '非AE与病史有关';
        } elseif ($type == 3) {
            return '非AE与合并用药有关';
        } elseif ($type == 4) {
            return '非AE其他原因';
        }
    }

    /**
     * Notes : 表单数据处理
     * @param $patientDatas
     * @param $checktimeDatas
     * @param $StageDatas
     * @param $itemsignatoryDatas
     * @param $item_id
     * @param $form_ids
     * @param $patient_ids
     * @param $number
     * @return array[]
     * Author:唐伯虎不虎
     * Date:2022/9/22 17:50
     *
     */
    public function formdataHandle($patientDatas, $checktimeDatas, $StageDatas, $itemsignatoryDatas, $item_id, $form_ids, $patient_ids, $number, $itemsig_ids,$source = 0,$patientchecktimeIndex = [])
    {
        //获取随机号别名
            $this->randomAlias = $this->LocalService()->itemFormField->getOneFieldVal('showfiled_name',"item_id = $item_id and is_del = 0 and var_name in ('RANDOM_GROUP_SYSTEM','RANGCA','RANDOM_GROUP_CUSTOM','RANGC')");

        //查询非AE
        $notae = $this->getnotAe($item_id, $itemsig_ids, $patient_ids);

        //查询指标AE
        $checknameae = $this->getchecknametAe($item_id, $itemsig_ids, $patient_ids);

        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //Ae表单ID
        $ae_id = $this->LocalService()->itemForm->getOneFieldVal('id',[
            'item_id' => $item_id,
            'group_id' => 5,
            'is_del' => 0,
        ]);
        //查询转状态受试者，应对数据中没有中心ID的情况
        $patientWhereArr = [
            'item_id' => $item_id,
            'is_del' => 0,
            new Operator('patient_status', Operator::OP_NE, 9)
        ];
        if ($itemsig_ids != 0) $patientWhereArr['itemsig_id'] = StringHelper::toArray($itemsig_ids);
        if ($patient_ids != 0) $patientWhereArr['id'] = StringHelper::toArray($patient_ids);
        $patient = $this->LocalService()->patient->fetchCol('itemsig_id',$patientWhereArr);

        //获取AE数据
        $patientAeformDatas = $this->getpatientAeform($item_id, $patient_ids, $itemsig_ids);

        $checknameaeArr = [];

        if (!empty($checknameae)) {
            $csaerelationContent = $this->LocalService()->itemCsaeRelation->fetchAll(['where'=>"is_del = 0",'columns'=>['content_id','patient_id','csae_id','new_ae_list_id']]);
            $relationAEDatas = [];
            foreach ($csaerelationContent as $csaeK => $csaeV){
                $csaeRelationDatas[$csaeV['patient_id'].'-'.$csaeV['csae_id']][] = $csaeV;

            }

            foreach ($checknameae as $k => $v) {

                if ($v['ae_type'] == 5) {
                    $csaerelationContent = array_column($csaeRelationDatas[$v['patient_id'].'-'.$v['relation_ae_id']],'content_id');
                } elseif ($v['ae_type'] == 6) {
                    $csaerelationContent = $csaeRelationDatas[$v['patient_id'].'-'.$v['id']][0];
                    if (empty($csaerelationContent)) continue;
                    $checknameAeWhere['where'] = [
                        'is_del' => 0,
                        'id' => $csaerelationContent['content_id']
                    ];
                    $checknameAeWhere['columns'] = ['id', 'patient_id', 'itemsig_id', 'data','csae_id'];
                    $checknameaecontent = $this->LocalService()->itemPatientAeContent->fetchone($checknameAeWhere);
                    if (empty($checknameaecontent)) continue;

                    $checknameaecontent['check_name'] = $checknameae[$checknameaecontent['csae_id']]['item_name'];
                    $checknameaecontent['checktime_id'] = $checknameae[$checknameaecontent['csae_id']]['checktime_id'];
                    $checknameaeArr[] = $checknameaecontent;
                    continue;
                }
                if (empty($csaerelationContent)) continue;

                $checkedBranch = $this->LocalService()->itemCsaeChecked->getOneFieldVal('branch', [
                    'is_del' => 0,
                    'csae_id' => $v['id'],
                    'new_id' => $v['relation_ae_id']
                ]);

                $checknameAeWhere['where'] = [
                    'is_del' => 0,
                    'id' => array_column($csaerelationContent,'content_id'),
                    'branch' => $checkedBranch,
                ];
                $checknameAeWhere['columns'] = ['id', 'patient_id', 'itemsig_id', 'data','csae_id'];
                $checknameaecontent = $this->LocalService()->itemPatientAeContent->fetchone($checknameAeWhere);

                $checknameaecontent['check_name'] = $v['item_name'];
                $checknameaecontent['checktime_id'] = $v['checktime_id'];
                $checknameaeArr[] = $checknameaecontent;
            }
        }

        //获取当前申请的表单
        $form = $this->getform($item_id, $form_ids);

        //查询受试者填写表单数据
        $patientformDatas = $this->getpatientform($item_id, $patient_ids, $form_ids, $itemsig_ids,'',1,0);

        //获取表单字段类型为单选/多选的数据
        $optionDatas = $this->getformoptions($item_id, $form_ids);

        //试验总结类数据汇总
        $summaryData = $this->getsummaryData($item_id, $itemsig_ids);

        //获取随机分组
        $randomDatas = $this->LocalService()->itemRandom->fetchCol('random_name', [
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        //获取研究分层
        $groupDatas = $this->LocalService()->itemRandgroup->fetchCol('group_name', [
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        //处理中心
        $itemsignatoryDatas = ArrayHelper::index($itemsignatoryDatas,'value');

        $formfieldDatas = $this->getformrules($item_id, $form_ids);
        //查询AE表单ID

        $AeFormId = $this->LocalService()->itemForm->fetchOne(['where' => [
            'is_del' => 0,
            'item_id' => $item_id,
            'group_id' => 5
        ], 'columns' => ['id']]);
        if (!empty($AeFormId)) {
            $aeformfieldDatas = $this->getformrules($item_id, $AeFormId['id']);
        }

        //查询受试者表【实验总结类表没有存储中心ID】
        $summaryPatient = $this->LocalService()->patient->fetchCol('itemsig_id', [
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        $item_fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称



        //获取评分管理员数据
        $this->LocalService()->itemForm->getUsingScoreUser(true);

        $scoreWhere['item_id'] = $item_id;

        if(empty($itemsig_ids)) {
            $itemsig_ids = $this->LocalService()->itemSignatory->fetchCol('id',[
                'item_id' => $item_fid,
            ]);
        }
        $scoreWhere['itemsig_id'] = $itemsig_ids;

        $scoreAdminUser = $this->LocalService()->itemForm->setRequestParams($scoreWhere)->getUsingScoreUser(true);

        //共享图片
        $gco_pool = [];
        $patientContentImg = [];
        list($gco_pool,$patientContentImg) = $this->getshareImg($item_id);

        //eCRF存储数组
        $eCRF = [];


        //表单数据存储数组
        $formDatas = [];

        //表单序号
        $formNumber = [];


        $summary = [
            ['id' => '0', 'name' => '脱离完成', 'type' => 0, 'code' => "", 'group_id' => 80],
            ['id' => '0', 'name' => 'AE（非AE解释）', 'type' => 0, 'code' => "", 'group_id' => 100],
            ['id' => '0', 'name' => 'AE（指标相关）', 'type' => 0, 'code' => "", 'group_id' => 110]
        ];

        $form = array_merge($summary, $form);

        //获取表单检查点关系表
        $checkcontentWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checkcontentWhere['columns'] = ['id', 'check_id', 'form_id'];

        $checkcontent = $this->LocalService()->itemCheckcontent->fetchAll($checkcontentWhere);


        $checkcontentDatas = [];
        foreach ($checkcontent as $k => $v) {
            $checkcontentDatas[$v['check_id']][$v['form_id']] = $v['form_id'];
        }

        $blind_method = $this->LocalService()->itemInfo->getOneFieldVal('blind_method', [
            'is_del' => 0,
            'id' => $item_fid,
        ]);//获取项目名称

        //处理数据
        foreach ($form as $key => $value) {
            //生成空数组 excel头
            $sheetData = $this->getformheader($value['group_id'], $item_id);

            //查询是否是分值表单
            $radio['where'] = [
                'is_score' => 1,
                'form_id' => $value['id']
            ];
            $radio['columns'] = ['id'];
            $radio_score = $this->LocalService()->itemFormFieldRadio->fetchOne($radio);
            $is_score = 0; //不是分值表单
            if (!empty($radio_score)) {
                $sheetData[0][] = '';
                $sheetData[1][] = '分值';
                $is_score = 1; //是分值表单
            }

            //如果此表单没有字段 则直接退出 [非实验总结类表单]
            if (empty($formfieldDatas[$value['id']]) && !in_array($value['group_id'], [80, 100, 110])) continue;

            if ($value['group_id'] != 80 && $value['group_id'] != 100) {
                if ($value['group_id'] == 110 ) {
                    if(empty($AeFormId)) continue;
                    $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$AeFormId['id']]['var_name']);
                    $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$AeFormId['id']]['name']);
                } else {
                    $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$value['id']]['var_name']);
                    $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$value['id']]['name']);
                }

            } elseif ($value['group_id'] == 80) {
                $sheetData[1] = array_merge($sheetData[1], ['类型', '转入/完成时间', '描述']);
            }

            if (empty($attrnumber)) {
                unset($sheetData[0][2], $sheetData[1][2]);
            }

            if (empty($attrname)) {
                unset($sheetData[0][3], $sheetData[1][3]);
            }
            $sheetData[0] = array_values($sheetData[0]);
            $sheetData[1] = array_values($sheetData[1]);

            if ($value['group_id'] == 5) {
                $patientformcontent = $patientAeformDatas[$value['id']];
            } elseif ($value['group_id'] == 80) {
                //试验总结类
                $patientformcontent = $summaryData;
            } elseif ($value['group_id'] == 100) {
                $patientformcontent = $notae;
            } elseif ($value['group_id'] == 110) {
                $patientformcontent = $checknameaeArr;
            } else {
                $patientformcontent = isset($patientformDatas[$value['id']]) ? $patientformDatas[$value['id']] : [];
            }

            //----------------------------------------------------------------------------
            /**
             * 兼容电话随访导出
             */
            if($source == 0 || !in_array($value['group_id'],[80,100,110])){
                $eCRF[$key][] = $value['name'];
                $eCRF[$key][] = isset($value['var_name']) ? $value['var_name'] : '';
            }
            //----------------------------------------------------------------------------

            //写入大数组
            $formname = str_replace("/", '-', $value['name']);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);
            $formname = str_replace("？", '', $formname);
            $formname = str_replace("（", '【', $formname);
            $formname = str_replace("）", '】', $formname);
            $formname = str_replace(" ", '', $formname);

            //如果当前表单没有受试者填写 则直接退出
            if (empty($patientformcontent)) {
                $formDatas[$formname] = $sheetData;
            }
            $dateClass = new \DateTime();
            if (!empty($patientformcontent)) {
                //排序数据
                $dataOrder = [];

                //数组Key
                $dataOrder_id = [];

                //数据数组
                $data = [];

                foreach ($patientformcontent as $contentKey => $contentVal) {

                    $patient_id = $contentVal['patient_id'];
                    //已删除受试者直接跳出
                    if (empty($patientDatas[$contentVal['itemsig_id']][$patient_id])) continue;

                    //评分表单如果不是管理员填写则跳过
                    if($value['is_using_score'] == 1 && !in_array($contentVal['create_user_id'],$scoreAdminUser)) continue;

                    if (!in_array($value['group_id'], [80, 100, 110, 3,4,5,1]) && empty($checkcontentDatas[$contentVal['checktime_id']][$value['id']])) {
                        continue;
                    }

                    if($contentVal['itemsig_id'] == 0)$contentVal['itemsig_id'] = $patient[$patient_id];

                    //数据主题
                    if(in_array($value['group_id'],[80, 100])){
                        $patientformContent = $contentVal;
                    }else{
                        $patientformContent = isset($contentVal['data']) ? json_decode($contentVal['data'], true) : [];
                        $patientformContent['checktime_id'] = $contentVal['checktime_id'];
                    }
                    if ($value['group_id'] == 110) {
                        $contentVal['id'] = $contentKey;
                    }

                    $dataOrder[$contentVal['id']]['patient_id'] = $patient_id;
                    //排序值处理
                    $dataOrder[$contentVal['id']]['sign'] = $itemsignatoryDatas[$contentVal['itemsig_id']]['order'];
                    $dataOrder[$contentVal['id']]['patient'] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['order'];
                    if ($value['type'] == 1 || $value['group_id'] == 100 || $value['group_id'] == 110 || $value['group_id'] == 3 || $value['group_id'] == 5) {
                        $dataOrder[$contentVal['id']]['type'] = $contentKey;
                    }
                    if (!in_array($value['group_id'], [3, 5])) {
//                        if ($value['group_id'] != 4 && $checktimeDatas[$patientformContent['checktime_id']]['order'] > $checktimeDatas[$patientchecktimeIndex[$patient_id]]['order'] && $checktimeDatas[$patientchecktimeIndex[$patient_id]]['is_isolate'] == 0) continue;

                        $dataOrder[$contentVal['id']]['checktime'] = $checktimeDatas[$patientformContent['checktime_id']]['order'];
                        if ($checktimeDatas[$patientformContent['checktime_id']]['stage_id'] != 0) {
                            $dataOrder[$contentVal['id']]['stage'] = $StageDatas[$checktimeDatas[$patientformContent['checktime_id']]['stage_id']]['order'];
                        } else {
                            $dataOrder[$contentVal['id']]['stage'] = 0;
                        }
                    } else {
                        $dataOrder[$contentVal['id']]['checktime'] = 0;
                        $dataOrder[$contentVal['id']]['stage'] = 0;
                    }

                    $dataOrderKey = $itemsignatoryDatas[$contentVal['itemsig_id']]['order'] . '-' . $patientDatas[$contentVal['itemsig_id']][$patient_id]['order'] . '-' . $dataOrder[$contentVal['id']]['checktime'] . '-' . $dataOrder[$contentVal['id']]['stage'];

                    if ($value['type'] == 1 || $value['group_id'] == 100 || $value['group_id'] == 110 || $value['group_id'] == 3 || $value['group_id'] == 5) $dataOrderKey .= "-" . $contentKey;

                    $dataKey = $contentKey + 2;

                    $dataOrder_id[$dataOrderKey] = $dataKey;
                    
                    //项目ID
                    $data[$dataKey][] = $number;
                    //中心编号
                    $data[$dataKey][] = $itemsignatoryDatas[$contentVal['itemsig_id']]['number'];

                    if (!empty($attrnumber)) {
                        //受试者编号
                        $data[$dataKey][] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['patient_number'];
                    }

                    if (!empty($attrname)) {
                        //受试者姓名
                        $data[$dataKey][] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['patient_name'];
                    }
                    //访视名称
                    if (!in_array($value['group_id'], [3, 5])) {

                        $checktimeName = $checktimeDatas[$patientformContent['checktime_id']]['check_name'];

                        $dataOrder[$contentVal['id']]['checktime'] = $checktimeDatas[$patientformContent['checktime_id']]['order'];

                        //试验总结类变更检查点名称
                        if ($value['group_id'] == 8 || $value['group_id'] == 1) {

                            $checktimeName = $this->LocalService()->itemPatientchecktime->getpatientTestsummaryNam($patient_id);
                        }

                        if ($checktimeDatas[$patientformContent['checktime_id']]['stage_id'] != 0) {
                            $data[$dataKey][] = $checktimeName . '-' . $StageDatas[$checktimeDatas[$patientformContent['checktime_id']]['stage_id']]['stage_name'];
                            $dataOrder[$contentVal['id']]['stage'] = $StageDatas[$checktimeDatas[$patientformContent['checktime_id']]['stage_id']]['order'];
                        } else {
                            $data[$dataKey][] = $checktimeName;
                            $dataOrder[$contentVal['id']]['stage'] = 0;
                        }
                    } else {
                        $dataOrder[$contentVal['id']]['checktime'] = 0;
                        $dataOrder[$contentVal['id']]['stage'] = 0;
                    }

                    //表单序号 默认值
                    $data[$dataKey][] = 1;

                    //脱离完成数据处理
                    if ($value['group_id'] == 80) {
                        $data[$dataKey][] = $this->getleavetype($contentVal['leave_type']);
                        $data[$dataKey][] = date('Y-m-d', $contentVal['leave_date']);
                        if($contentVal['stage_remark'] == 'null') $contentVal['stage_remark'] = '';
                        $data[$dataKey][] = $contentVal['stage_remark'];
                        continue;
                    }

                    //非AE
                    if ($value['group_id'] == 100) {
                        $data[$dataKey][] = $contentVal['item_name'];
                        $data[$dataKey][] = $this->getarType($contentVal['ae_type']);
                        $data[$dataKey][] = $contentVal['ae_remarks'];
                        continue;
                    }


                    //处理数据含有“-”符号，截取符号前的ID
                    foreach ($patientformContent as $contentK => $contentV) {
                        if (count(explode('-', $contentK)) > 1) {
                            $arr = explode('-', $contentK);
                            $arrCount = count($arr);
                            $unsetNumber = $arrCount - ceil($arrCount / 2) + 1;

                            for ($i = 1; $i < $unsetNumber; $i++) {
                                unset($arr[count($arr) - 1]);
                            }

                            $str = implode('-', $arr);

                            $patientformContent[$str] = $contentV;
                        }
                    }

                    //分值表单
                    if ($is_score == 1) {
                        if (isset($patientformContent['score'])) {
                            $data[$dataKey][] = $patientformContent['score'];
                        } else {
                            $data[$dataKey][] = [];
                        }
                    }

                    //AE表单
                    if ($value['group_id'] == 110) {
                        $data[$dataKey][] = $contentVal['check_name'];
                    }
                    if ($value['group_id'] == 110) {
                        $formfield = $aeformfieldDatas[$AeFormId['id']]['data'];
                    } else {
                        $formfield = $formfieldDatas[$value['id']]['data'];
                    }

//                    $gco_pool,$patientContentImg
                    //处理表单字段
                    foreach ($formfield as $fieldKey => $fieldVal) {
                        //共享图片
                        if(isset($fieldVal['is_share']) && $fieldVal['is_share'] == 1){
                            //判断是否上传图片
                            if(isset($patientContentImg[$patient_id.'-'.$patientformContent['checktime_id'].'-'.$gco_pool[$value['id']]['gco_pool']])){
                                $data[$dataKey][] = '已上传图片';
                            }else{
                                $data[$dataKey][] = '未上传图片';
                            }
                            continue;
                        }
//                        $resultKey = $fieldVal['id'];
                        $resultKey = $fieldVal['patents'];
//                        if(isset($fieldVal['patents'])) $resultKey .= '-'.$fieldVal['patents'];

                        if (!isset($patientformContent[$resultKey])) {
                            if ($fieldVal['type'] == 19){
                                $data[$dataKey][] = '已上传图片/文件';
                            }else{
                                $data[$dataKey][] = '';
                            }
                            continue;
                        }

                        if ($fieldVal['var_name'] == 'RANDOM_GROUP_CUSTOM' || $fieldVal['var_name'] == 'RANGC') {
                            //研究分层
                            $data[$dataKey][] = '';
                            if ($blind_method == 0) {
                                //随机分组
                                $data[$dataKey][] = $randomDatas[$patientDatas[$contentVal['itemsig_id']][$patient_id]['random_id']];
                            }
                            //随机号
                            $data[$dataKey][] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['random_number'];
                        }
                        //随机分组  研究分层
                        if ($fieldVal['var_name'] == 'RANDOM_GROUP_SYSTEM' || $fieldVal['var_name'] == 'RANGCA') {
                            //研究分层
                            $data[$dataKey][] = $groupDatas[$patientDatas[$contentVal['itemsig_id']][$patient_id]['randgroup_id']];
                            if ($blind_method == 0) {
                                //随机分组
                                $data[$dataKey][] = $randomDatas[$patientDatas[$contentVal['itemsig_id']][$patient_id]['random_id']];
                            }
//                            var_dump($patientDatas,$patientDatas[$contentVal['itemsig_id']][$patient_id]['random_number']);die;
                            //随机
                            $data[$dataKey][] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['random_number'];
                            continue;
                        }

                        if ($fieldVal['var_name'] == 'CHECKIMG') {
                            if ($patientformContent[$resultKey] != '[]') {
                                $data[$dataKey][] = '已上传图片';
                            } else {
                                $data[$dataKey][] = '未上传图片';
                            }
                            continue;
                        }

                        if ($fieldVal['var_name'] == 'OUTPLANCHECK' || $fieldVal['var_name'] == 'OPCH') {
                            if ($patientformContent[$resultKey] == '[]') {
                                $data[$dataKey][] = '无';
                            } else {
                                $data[$dataKey][] = '有';
                            }
                            continue;
                        }

                        if ($fieldVal['type'] == 10 || $fieldVal['type'] == 12) {
                            if(isset($patientformContent[$resultKey]) && !empty($patientformContent[$resultKey]) && isset($optionDatas[$fieldVal['id']][$patientformContent[$resultKey]])){
                                $data[$dataKey][] = $optionDatas[$fieldVal['id']][$patientformContent[$resultKey]];
                            }else{
                                $data[$dataKey][] = '';
                            }

                        } elseif ($fieldVal['type'] == 11) {
                            if (!is_array($patientformContent[$resultKey])) {
                                $options = explode(',', $patientformContent[$resultKey]);
                            } else {
                                $options = $patientformContent[$resultKey];
                            }
                            $optionResult = [];
                            foreach ($options as $optionKey => $optionVal) {
                                $optionResult[] = $optionDatas[$fieldVal['id']][$optionVal];
                            }
                            $data[$dataKey][] = implode(',', $optionResult);
                        } elseif ($fieldVal['type'] == 13 || $fieldVal['type'] == 14 || $fieldVal['type'] == 19) {
                            if (!empty($patientformContent[$resultKey]) && $patientformContent[$resultKey] != '[]') {
                                $data[$dataKey][] = '已上传图片/文件';
                            } else {
                                $data[$dataKey][] = '未上传图片/文件';
                            }
                        } else {

                            //年月日  3   年月日时分秒 5
                            if($fieldVal['type'] == 3){
                                $data[$dataKey][] = !empty($patientformContent[$resultKey]) ? date('Y-m-d',strtotime(trim($patientformContent[$resultKey]))) : '';
                            }elseif($fieldVal['type'] == 5){
                                $data[$dataKey][] = !empty($patientformContent[$resultKey]) ? date('Y-m-d H:i:s',strtotime(trim($patientformContent[$resultKey]))) : '';
                            }else{

                                if(is_array($patientformContent[$resultKey])){
                                    $text = '';
                                    foreach ($patientformContent[$resultKey] as $textK =>$textV){
                                        $text .= $textV == 'null' ? '' : $textV;
                                    }
                                    $data[$dataKey][] = trim($text);
                                }else{
                                    $data[$dataKey][] = $patientformContent[$resultKey] == 'null' ? '' : trim($patientformContent[$resultKey]);
                                }
                            }
                        }
                    }
                }

                unset($patientformcontent);
                $O1 = [];
                $O2 = [];
                $O3 = [];
                $O4 = [];

                //数组排序
                foreach ($dataOrder as $k => $v) {
                    $O1[$k] = $v['sign'];
                    $O2[$k] = $v['patient'];
                    $O3[$k] = $v['stage'];
                    $O4[$k] = $v['checktime'];
                    //一对多表单
                    if ($value['type'] == 1) {
                        $O5[$k] = $v['type'];
                    }
                }
                if ($value['type'] == 0) {
                    array_multisort($O1, $O2, $O3, $O4, $dataOrder);
                } else {
                    array_multisort($O1, $O2, $O3, $O4, $dataOrder);
                }

                if (!in_array($value['group_id'], [3, 5])) {
                    $SerialNoKey = 5;
                } else {
                    $SerialNoKey = 4;
                }
                if (empty($attrnumber)) $SerialNoKey -= 1;
                if (empty($attrname)) $SerialNoKey -= 1;

                $patientformnumber = [];
                foreach ($dataOrder as $ks => $vs) {
                    //$SerialNoKey 表单序号位置


                    $dataOrderKey = $vs['sign'] . '-' . $vs['patient'] . '-' . $vs['checktime'] . '-' . $vs['stage'];

                    //一对多类型的表单 在原来 中心-受试者-表单-阶段 字符串基础上在拼接一个一对多的ID
                    if ($value['type'] == 1 || $value['group_id'] == 100 || $value['group_id'] == 110 || $value['group_id'] == 3 || $value['group_id'] == 5) $dataOrderKey .= "-" . $vs['type'];

                    //如果当前受试者已经填写过
                    if (isset($patientformnumber[$vs['patient_id']])) {
                        $patientformnumber[$vs['patient_id']] = $patientformnumber[$vs['patient_id']] + 1;
                        $data[$dataOrder_id[$dataOrderKey]][$SerialNoKey] = $patientformnumber[$vs['patient_id']];
                    } else {
                        $patientformnumber[$vs['patient_id']] = 1;
                        $data[$dataOrder_id[$dataOrderKey]][$SerialNoKey] = 1;
                    }

                    $sheetData[$ks + 2] = $data[$dataOrder_id[$dataOrderKey]];
                }
                unset($dataOrder);

            }
            $formDatas[$formname] = $sheetData;
            unset($sheetData);
        }
        //删除数据 释放内存
        unset($patientContentImg,$patientformDatas,$optionDatas,$randomDatas);
        unset($form,$notae,$checkcontent);
        unset($formNumber);
        unset($optionDatas);
        unset($patientformDatas);
        unset($patientAeformDatas);
        unset($formfieldDatas);
        unset($formNumber);
        if($source == 1){
            unset($formDatas['脱离完成'],$formDatas['AE【非AE解释】'],$formDatas['AE【指标相关】']);
            return $formDatas;
        }else{
            return [$eCRF, $formDatas];
        }
    }

    /**
     * Notes : 表单模板
     * @param $data
     * Author:唐伯虎不虎
     */
    public function excelmodel($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $create_time = $data['create_time'] ?: 0;       //受试者ID
        $StageDatas = $this->getItemstage($item_id);
        $form_ids = 0;
        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, 9);


        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        $catalogue = [];
        $formData = [];
        $changetype = [];
        list($catalogue, $formData, $changetype) = $this->formmodel($patientDatas, $checktimeDatas, $StageDatas, $itemsignatoryDatas, $item_id, $form_ids, $patient_id, $itemInfo['number'], $itemsig_id);

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];

        $fileName = $itemInfo['name'] . '表单模板-' . $create_time . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, $catalogue[0][0]);
        $excelFileHandle = $fileObject->getHandle();


        $format = new Format($excelFileHandle);

        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        $signDatas = [];
        foreach($itemsignatoryDatas as $k=>$v){
            $signDatas[$v['value']]['label'] = $v['label'];
            $signDatas[$v['value']]['number'] = $v['number'];
        }

        //循环指标数据生成sheet
        foreach ($formData as $k => $v) {

            if (!empty($patientDatas)) {
                $p_i = 2;
                foreach($patientDatas as $signK=>$signV){
                    foreach ($signV as $ks => $vs) {
                        $formData[$k][$p_i][] = $itemInfo['number'];
                        $formData[$k][$p_i][] = $signDatas[$vs['itemsig_id']]['number'];
                        $formData[$k][$p_i][] = $vs['patient_number'];
                        $formData[$k][$p_i][] = $vs['patient_name'];
                        ++$p_i;
                    }
                }
            }

            if ($k == $catalogue[0][0]) {
                unset($formData[$k][0]);
                $fileObject->header($v[0])->data($formData[$k]);
                $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
                continue;
            }

            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }

            $fileObject->addSheet($sheetName)->data($formData[$k]);

            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }


        //输出数据
        $filePath = $fileObject->output();
    }

    public function formmodel($patientDatas, $checktimeDatas, $StageDatas, $itemsignatoryDatas, $item_id, $form_ids, $patient_ids, $number, $itemsig_ids)
    {
        //$form_ids = '839';
        //获取当前申请的表单
        $form = $this->getform($item_id, $form_ids);

        //获取表单字段类型为单选/多选的数据
        $optionDatas = $this->getformoptions($item_id, $form_ids);

        //处理中心
        foreach ($itemsignatoryDatas as $k => $v) {
            $itemsignatoryDatas[$v['value']] = $v;
            unset($itemsignatoryDatas[$k]);
        }

        //表单字段
        $formfieldDatas = $this->_getexcelmodelformrules($item_id, $form_ids);
        //eCRF存储数组
        $eCRF = [];

        //表单数据存储数组
        $formDatas = [];

        //表单序号
        $formNumber = [];

        //获取表单检查点关系表
        $checkcontentWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checkcontentWhere['columns'] = ['id', 'check_id', 'form_id'];
        $checkcontent = $this->LocalService()->itemCheckcontent->fetchAll($checkcontentWhere);


        $checkcontentDatas = [];
        foreach ($checkcontent as $k => $v) {
            $checkcontentDatas[$v['check_id']][$v['form_id']] = $v['form_id'];
        }
        $AeFormId = $this->LocalService()->itemForm->fetchOne(['where' => [
            'is_del' => 0,
            'item_id' => $item_id,
            'group_id' => 5,
        ], 'columns' => ['id']]);
        //处理数据
        $typeArr = [2, 3, 4, 5];
        $changetype = [];
        foreach ($form as $key => $value) {
            //生成空数组 excel头
            $sheetData = $this->getformheader($value['group_id'], $item_id);

            if ($value['group_id'] == 3) {
                unset($sheetData[0][4], $sheetData[1][4]);
            } elseif ($value['group_id'] == 5) {
                unset($sheetData[0][4], $sheetData[1][4]);
            } elseif ($value['group_id'] == 6) {
                unset($sheetData[0][5], $sheetData[1][5]);
            }
            //如果此表单没有字段 则直接退出 [非实验总结类表单]
            if (empty($formfieldDatas[$value['id']]) && !in_array($value['group_id'], [8, 10, 11])) continue;

            $defaultsheetCount = count($sheetData[0]);
            if ($value['group_id'] != 8 && $value['group_id'] != 10) {
                if ($value['group_id'] == 11) {
                    $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$AeFormId['id']]['var_name']);
                    $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$AeFormId['id']]['name']);
                } else {
                    $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$value['id']]['var_name']);
                    $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$value['id']]['name']);
                }
            } elseif ($value['group_id'] == 8) {
                $sheetData[1] = array_merge($sheetData[1], ['类型', '转入/完成时间', '描述']);
            }else{
                $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$value['id']]['var_name']);
                $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$value['id']]['name']);
            }

            $eCRF[$key][] = $value['name'];
            $eCRF[$key][] = $value['var_name'];

            //排序数据
            $dataOrder = [];
            //数据数组
            $data = [];

            foreach ($patientDatas as $patientK => $patientV) {
                foreach ($patientV as $contentKey => $contentVal) {

                    $dataKey = $contentKey + 2;

                    //项目ID
                    $data[$dataKey][] = $number;

                    //中心编号
                    $data[$dataKey][] = $itemsignatoryDatas[$contentVal['itemsig_id']]['number'];

                    //受试者编号
                    $data[$dataKey][] = $contentVal['patient_number'];

                    //受试者姓名
                    $data[$dataKey][] = $contentVal['patient_name'];

                }
            }
            unset($dataOrder);

            //写入大数组
            $formname = str_replace("/", '-', $value['name']);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);
            $formname = str_replace("？", '', $formname);

            // 2、3、4、5改成文本
            foreach ($formfieldDatas[$value['id']]['data'] as $k => $v) {
                if (in_array($v['type'], $typeArr)) {
                    $changetype[$formname][] = $defaultsheetCount + $k;
                }
            }

            $formDatas[$formname] = $sheetData;
        }

        //查询锚点ID字段所对应的表单
        $anchordata = $this->LocalService()->itemFormField->fetchCol('form_id', [
            'is_del' => 0,
            'item_id' => $item_id,
            'is_anchor' => 1,
        ]);

        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'id' => $anchordata,
        ];
        $whereArr['columns'] = ['id', 'name'];
        $whereArr['order'] = 'order';
        $anchorformdata = $this->LocalService()->itemForm->fetchAll($whereArr);

        $first = [];
        $firsteCRF = [];
        foreach ($anchorformdata as $anckorK => $anchorV) {
            $first[$anchorV['name']] = $formDatas[$anchorV['name']];
            $firsteCRF[$anchorV['id']] = $eCRF[$anchorV['id']];
            unset($formDatas[$anchorV['name']]);
            unset($eCRF[$anchorV['id']]);
        }

        $formDatas = array_merge($first, $formDatas);

        $eCRF = array_merge($firsteCRF, $eCRF);
        //删除数据 释放内存
        unset($form);
        unset($formNumber);
        unset($optionDatas);
        unset($patientformDatas);
        unset($patientAeformDatas);
        unset($formfieldDatas);
        unset($formNumber);

        return [$eCRF, $formDatas, $changetype];
    }


    public function checkmodel($patientDatas,$checktimeDatas, $StageDatas,$itemsignatoryDatas, $item_id,$number)
    {
        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        $formDatas = [];
        //中心
        foreach ($itemsignatoryDatas as $k => $v) {
            $itemsignatoryDatas[$v['value']] = $v;
            unset($itemsignatoryDatas[$k]);
        }

        //获取检查类表单
        $checkFormDatas = $this->LocalService()->itemForm->fetchAll([
            'where'=>['is_del'=>0,'item_id'=>$item_id,'group_id'=>7],
            'columns'=>['id','name','checklist_id','code']
        ]);

        //检查点表单关联表
        $checkcontentWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'form_id'=>array_column($checkFormDatas,'id')
        ];
        $checkcontentWhere['columns'] = ['id', 'check_id', 'form_id'];
        $checkcontentWhere['group'] = ['form_id'];
        $checkcontent = $this->LocalService()->itemCheckcontent->fetchAll($checkcontentWhere);

        $contentDatas = [];
        foreach($checkcontent as $k=>$v){
            $contentDatas[$v['form_id']] = $v['form_id'];
        }
        unset($checkcontentWhere,$checkcontent);

        //获取检查项
        $checknameDatas = $this->LocalService()->itemCheckname->fetchAll([
            'where'=>['is_del'=>0,'item_id'=>$item_id]
        ]);

        $checkname = [];
        foreach ($checknameDatas as $k=>$v){
            $checkname[$v['category_id']][] = $v;
        }

        foreach ($checkFormDatas as $key => $value) {
            if(!isset($contentDatas[$value['id']])) continue;

            //生成空数组 excel头
            $sheetData = $this->getformheader($value['group_id'], $item_id);

            $sheetData[0][] = "LBDAT";
            $sheetData[1][] = "采集日期";
            //指标名称
            $sheetData[0][] = "LBTEST";
            $sheetData[1][] = "指标名称";
            //测量结果
            $sheetData[0][] = "LBORRES";
            $sheetData[1][] = "测量结果";
            //单位
            $sheetData[0][] = "LBORRESU";
            $sheetData[1][] = "计数单位";
            //范围下限
            $sheetData[0][] = "LBORNRLO";
            $sheetData[1][] = "最小值";
            //范围上限
            $sheetData[0][] = "LBORNRHI";
            $sheetData[1][] = "最大值";


            $dataKey = 2;
            foreach ($patientDatas as $patientK => $patientV) {
                foreach ($patientV as $contentKey => $contentVal) {

                    foreach ($checkname[$value['checklist_id']] as $checkValue){
                        //项目编号
                        $sheetData[$dataKey][] = $number;

                        //中心编号
                        $sheetData[$dataKey][] = $itemsignatoryDatas[$contentVal['itemsig_id']]['number'];

                        //受试者编号

                        $sheetData[$dataKey][] = empty($attrnumber) ? '' : $contentVal['patient_number'];

                        //受试者姓名
                        $sheetData[$dataKey][] = empty($attrname) ? '' : $contentVal['patient_name'];

                        //访视
                        $sheetData[$dataKey][] = '';

                        //表单序号
                        $sheetData[$dataKey][] = '';

                        //采集日期
                        $sheetData[$dataKey][] = '';

                        //指标名称
                        $sheetData[$dataKey][] = $checkValue['name'];
                        //测量结果
                        $sheetData[$dataKey][] = '';
                        //单位
                        $sheetData[$dataKey][] = $checkValue['unit'];
                        //范围下限
                        $sheetData[$dataKey][] = $checkValue['min_val'];
                        //范围上限
                        $sheetData[$dataKey][] = $checkValue['max_val'];
                        ++$dataKey;
                    }
                }
            }

            //写入大数组
            $formname = str_replace("/", '-', $value['name']);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);
            $formname = str_replace("？", '', $formname);

            $formDatas[$formname] = $sheetData;
        }

        return [$formDatas,$checkFormDatas[0]['name']];
    }


    public function getHeader($group_id,$item_id,$form_id)
    {
        $sheetData = $this->getformheader($group_id, $item_id);

        if($group_id == 7){
            $sheetData[0][] = "LBDAT";
            $sheetData[1][] = "采集日期";
            //指标名称
            $sheetData[0][] = "LBTEST";
            $sheetData[1][] = "指标名称";
            //测量结果
            $sheetData[0][] = "LBORRES";
            $sheetData[1][] = "测量结果";
            //单位
            $sheetData[0][] = "LBORRESU";
            $sheetData[1][] = "计数单位";
            //范围下限
            $sheetData[0][] = "LBORNRLO";
            $sheetData[1][] = "最小值";
            //范围上限
            $sheetData[0][] = "LBORNRHI";
            $sheetData[1][] = "最大值";
        }else{
            $form = $this->getform($item_id, $form_id);
            //获取表单字段类型为单选/多选的数据
            $optionDatas = $this->getformoptions($item_id, $form_id);

            //表单字段
            $formfieldDatas = $this->_getexcelmodelformrules($item_id, $form_id);

            if ($group_id == 3) {
                unset($sheetData[0][4], $sheetData[1][4]);
            } elseif ($group_id == 5) {
                unset($sheetData[0][4], $sheetData[1][4]);
            } elseif ($group_id == 6) {
                unset($sheetData[0][5], $sheetData[1][5]);
            }

            //如果此表单没有字段 则直接退出 [非实验总结类表单]
            if (empty($formfieldDatas[$form_id]) && !in_array($group_id, [8, 10, 11])){
                return [];
            }

            $defaultsheetCount = count($sheetData[0]);
            if ($group_id != 8 && $group_id != 10) {
                if ($group_id == 11) {
                    $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$form_id]['var_name']);
                    $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$form_id]['name']);
                } else {
                    $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$form_id]['var_name']);
                    $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$form_id]['name']);
                }
            } elseif ($group_id == 8) {
                $sheetData[1] = array_merge($sheetData[1], ['类型', '转入/完成时间', '描述']);
            }else{
                $sheetData[0] = array_merge($sheetData[0], $formfieldDatas[$form_id]['var_name']);
                $sheetData[1] = array_merge($sheetData[1], $formfieldDatas[$form_id]['name']);
            }
        }
        return $sheetData;
    }

    /**
     * Notes : 获取项目拓展属性
     * @param $item_id
     * @return array|\phpDocumentor\Reflection\Types\Mixed
     * Author:唐伯虎不虎
     */
    public function patientattr($item_id)
    {
        $attr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'is_hide' => 0,
        ];
        $attr['columns'] = ['id', 'attr_name', 'attr_field', 'attr_type'];
        $attr['order'] = 'attr_order';
        return $this->LocalService()->patientattrs->fetchAll($attr);
    }

    /**
     * Notes : 拓展属性处理
     * @param $item_id
     * @param $patientDatas
     * @param $itemsignatoryDatas
     * @param $number
     * @return \string[][]
     * Author:唐伯虎不虎
     */
    public function getpatientAttr($item_id, $patientDatas, $itemsignatoryDatas, $number)
    {
        //header
        $attrHeader = $this->getformheader(9, $item_id);

        //拓展属性
        $attr = $this->patientattr($item_id);

        //获取项目下单选、多选 选项数据
        $attrcontent = $this->LocalService()->patientattrs->fetchCol('content', [
            'is_del' => 0,
            'item_id' => $item_id,
            'attr_type' => [3, 4]
        ]);

        $selectData = [];

        if (!empty($attrcontent)) {
            foreach ($attrcontent as $k => $v) {
                if (empty($v)) continue;
                $select = json_decode($v, true);
                foreach ($select as $key => $value) {
                    $selectData[$k . '-' . $value['select_variable']] = $value['select_name'];
                }
            }
        }

        $randGroup = $this->LocalService()->itemRandgroup->fetchCol('group_name', [
            'is_del' => 0,
            'item_id' => $item_id,
        ]);

        //受试者
        $patientKey = 2;
        $cardDatas = $this->LocalService()->patientCard->fetchCol('patient_id', [
            'is_del' => 0,
            'item_id' => $item_id,
        ]);
        foreach ($itemsignatoryDatas as $v) {
            foreach ($patientDatas[$v['value']] as $key => $value) {
                //项目编号
                $attrHeader[$patientKey][] = $number;
                //中心编号
                $attrHeader[$patientKey][] = $v['number'];

                $patient_content = json_decode($value['patient_content'], true);

                $patientttrContentData = [];

                foreach ($patient_content as $patientcontentKey => $patientcontentValue) {
                    $patientttrContentData[$patientcontentValue['id']] = $patientcontentValue['value'];
                }

                //自定义拓展属性
                foreach ($attr as $attrK => $attrV) {
                    if (!isset($patientttrContentData[$attrV['id']]) && $attrV['attr_type'] != 8) {
                        $attrHeader[$patientKey][] = '';
                        continue;
                    }
                    if ($attrV['attr_type'] == 3 || ($attrV['attr_type'] == 7 && $attrV['attr_field'] != 'randgroup_id' && $attrV['attr_field'] != 'signatory_user_id')) {
                        $attrHeader[$patientKey][] = $selectData[$attrV['id'] . '-' . $patientttrContentData[$attrV['id']]];
                    } elseif ($attrV['attr_type'] == 4) {
                        $checkArr = [];
                        foreach ($patientttrContentData[$attrV['id']] as $checkboxKey => $checkboxVal) {
                            $checkArr[] = $selectData[$attrV['id'] . '-' . $checkboxVal];
                        }
                        $attrHeader[$patientKey][] = implode(',', $checkArr);
                    } elseif ($attrV['attr_type'] == 7 && $attrV['attr_field'] == 'randgroup_id') { //研究分层
//                        $attrHeader[$patientKey][] = $randGroup[$patientttrContentData[$attrV['id']]];
                        $attrHeader[$patientKey][] = $randGroup[$value['randgroup_id']] ?: '';
                    } elseif ($attrV['attr_type'] == 7 && $attrV['attr_field'] == 'signatory_user_id') { //研究医生
                        if (!empty($patientttrContentData[$attrV['id']])) {
                            $signuserResult = $this->LocalService()->signatoryUser->fetchCol('user_name', "id = " . $patientttrContentData[$attrV['id']]);
                            $attrHeader[$patientKey][] = $signuserResult[$patientttrContentData[$attrV['id']]];
                        } else {
                            $attrHeader[$patientKey][] = '';
                        }
                    } elseif ($attrV['attr_type'] == 8) {
                        if (in_array($value['id'], $cardDatas)) {
                            $attrHeader[$patientKey][] = '已上传';
                        } else {
                            $attrHeader[$patientKey][] = '未上传';
                        }
                    } else {
                        $attrHeader[$patientKey][] = $patientttrContentData[$attrV['id']];
                    }
                }
                ++$patientKey;
            }
        }

        return $attrHeader;
    }

    /**
     * Notes : 获取Excel sheet header
     * @param $group_id
     * @return \string[][]
     * Author:唐伯虎不虎
     * Date:2022/9/19 15:14
     */
    public function getformheader($group_id, $item_id)
    {
        if ($group_id == 1) {
            $data = Exportenum::RAND_CHECK;
        } elseif ($group_id == 3) { //实验总结类
            $data = Exportenum::Experimentsummary;
        } elseif ($group_id == 5) {
            $data = Exportenum::AE;
        } elseif ($group_id == 2 || $group_id == 7) { //随机分组
            $data = Exportenum::RAND_CHECK;
        } elseif ($group_id == 9) { //受试者拓展属性
            $data = [['INVSITE', 'PT'], ['项目ID', '中心编号']];
            $result = $this->patientattr($item_id);
            foreach ($result as $k => $v) {
                $data[0][] = $v['attr_field'];
                $data[1][] = $v['attr_name'];
            }
        } elseif ($group_id == 100) { //受试者拓展属性
            $data = Exportenum::Not_AE;
        } elseif ($group_id == 110) { //受试者拓展属性
            $data = Exportenum::CheckAE;
        } else {
            $data = Exportenum::DEFAULT;
        }
        return $data;
    }

    /**
     * Notes : 脱离完成类型
     * @param $leave_type
     * @return string
     * Author:唐伯虎不虎
     * Date:2022/9/19 9:25
     */
    public function getleavetype($leave_type)
    {
        if ($leave_type == 1) {
            $leave_name = '脱落';
        } elseif ($leave_type == 2) {
            $leave_name = '筛败';
        } elseif ($leave_type == 3) {
            $leave_name = '完成';
        } elseif ($leave_type == 4) {
            $leave_name = '中止';
        }
        return $leave_name;
    }

    /**
     * Notes :导出已识别已锁定的数据
     * @param $item_id
     * @param int $itemsig_id
     * @param int $patient_id
     * @param int $patient_status
     * @param int $category_id
     * Author:唐伯虎不虎
     * Date:2022/8/3 13:58
     */
    public function formdata($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $exportpatientdata_type = $data['exportpatientdata_type'];       //表单、化验单表单
        $patient_status = $data['patient_status'] ?: '10';       //受试者脱离完成状态
        $category_id = $data['category_id'] ?: '0';       //检查项分类ID
        $form_ids = $data['form_ids'] ?: '0';       //检查项分类ID
        $create_time = $data['create_time'];       //创建时间
        $hide_type = $data['hide_type'];           //是否导出隐私字段的值 0 不导出  1 导出
        $this->hide_type = $hide_type;
        //当前项目阶段

        $StageDatas = $this->getItemstage($item_id);

        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, $patient_status);

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        $formData = [];

        //受试者拓展属性
        $patientattrData['受试者信息'] = $this->getpatientAttr($item_id, $patientDatas, $itemsignatoryDatas, $itemInfo['number']);

        //获取受试者当前所处检查点的排序号
        $patientchecktimeWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'is_now_state' => 1,
        ];
        if (!empty($patient_id)) $patientchecktimeWhere['where']['patient_id'] = StringHelper::toArray($patient_id);
        if (!empty($itemsig_id)) $patientchecktimeWhere['where']['itemsig_id'] = StringHelper::toArray($itemsig_id);
        $patientchecktimeWhere['columns'] = ['patient_id', 'check_order','checktime_id'];
        $patientchecktimeDatas = $this->LocalService()->itemPatientchecktime->fetchAll($patientchecktimeWhere);
        $patientchecktime = [];
        $patientchecktimeIndex = [];
        foreach ($patientchecktimeDatas as $key => $value) {
            $patientchecktime[$value['patient_id']] = $value['check_order'];
            $patientchecktimeIndex[$value['patient_id']] = $value['checktime_id'];
        }
        unset($patientchecktimeDatas);

        //处理表单数据
        if ($form_ids != '' && in_array($exportpatientdata_type, [1, 3])) {
            list($catalogue, $formData) = $this->formdataHandle($patientDatas, $checktimeDatas, $StageDatas, $itemsignatoryDatas, $item_id, $form_ids, $patient_id, $itemInfo['number'], $itemsig_id,0,$patientchecktimeIndex);
        }
        $catalogue = array_merge([['受试者信息', '']], $catalogue);

        $formData = array_merge($patientattrData, $formData);
        //化验单
        if ($category_id != '' && in_array($exportpatientdata_type, [2, 3])) {
            //受试者编号是否为隐私字段
            $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
                'is_del' => 0,
                'item_id' => $item_id,
                'attr_field' => 'number',
                'is_hide' => 0,
            ]);//获取项目名称

            //受试者姓名是否为隐私字段
            $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
                'is_del' => 0,
                'item_id' => $item_id,
                'attr_field' => 'name',
                'is_hide' => 0,
            ]);//获取项目名称

            $whereArr['where'] = [
                'is_del' => 0,
                'item_id' => $item_id,
                'group_id' => [7, 8],
                new Operator('checklist_id', Operator::OP_GT, 0),
            ];
            if ($category_id != 0) {
                $whereArr['where']['id'] = StringHelper::toArray($category_id);
            }
            $whereArr['columns'] = ['id', 'name', 'code', 'checklist_id', 'group_id', 'var_name'];

            $formDatas = $this->LocalService()->itemForm->fetchAll($whereArr);


            $content = $this->LocalService()->itemCheckcontent->fetchCol('form_id', [
                'is_del' => 0,
                'item_id' => $item_id,
            ]);
            $content = array_flip(array_unique($content));

            foreach($formDatas as $k=>$v){
                if(!isset($content[$v['id']])){
                    unset($formDatas[$k]);
                }
            }
            $formDatas = array_values($formDatas);


            //检查点-条目
            $contentwhereArr['where'] = [
                'is_del' => 0,
                'item_id' => $item_id,
            ];
            if ($category_id != 0) {
                $contentwhereArr['where']['form_id'] = StringHelper::toArray($category_id);
            }
            $contentwhereArr['columns'] = ['id', 'check_id', 'form_id'];
            $contentwhereArr['order'] = 'order';
            $checkcontentDatas = $this->LocalService()->itemCheckcontent->fetchAll($contentwhereArr);
            $contentArr = [];
            foreach ($checkcontentDatas as $contentK => $contentV) {
                $contentArr[$contentV['check_id']][$contentV['form_id']] = $contentV;
            }
            unset($checkcontentDatas);
            $checklistWhere = [
                'item_id' => $item_id,
                'is_del' => 0,
                new Operator('checklist_id', Operator::OP_GT, 0)
            ];
            if ($category_id != 0) {
                $checklistWhere['id'] = StringHelper::toArray($category_id);
            }

            //查询化验单表单是否有计划外检查字段
            $formfieldWhere = [
                'is_del' => 0,
                'item_id' => $item_id,
                'var_name' => ['OUTPLANCHECK', 'OPCH']
            ];
            if ($category_id != 0) {
                $contentwhereArr['form_id'] = StringHelper::toArray($category_id);
            }
            $OPCHDatas = [];
            $OPCHDatas = $this->LocalService()->itemFormField->fetchCol('form_id',$formfieldWhere);
            $OPCHDatas = array_flip($OPCHDatas);

            if (!empty($formDatas)) {

                $checklistdata = $this->LocalService()->itemForm->fetchCol('checklist_id', $checklistWhere);

                $checklistdatastr = implode(',', $checklistdata);
                //获取当前项目下符合条件的检查分类以及检查项
                $checknameData = $this->getItemcheckname($item_id, $checklistdatastr);

                //检查项
                $checknameDatas = $checknameData['checknameDatas'];


                //获取当前项目分类
                $randomDatas = $this->LocalService()->itemRandom->fetchCol('flowcat_id', [
                    'is_del' => 0,
                    'item_id' => $item_id,
                ]);

                //获取受试者填写化验单表单是否开局

                if (!empty($category_id)) {
                    $form_ids = $category_id;
                } else {
                    $checkdataWhere = [
                        'is_del' => 0,
                        'item_id' => $item_id,
                        new Operator('checklist_id', Operator::OP_GT, 0),
                    ];
                    $checklistdata = $this->LocalService()->itemForm->fetchCol('id', $checkdataWhere);
                    $form_ids = implode(',', $checklistdata);
                }

                //查询化验单表单备注说明
                $patientcheckdataWhere['where'] = [
                    'is_del' => 0,
                    'item_id' => $item_id,
                    'form_id' => StringHelper::toArray($form_ids),
                    new Operator('is_yc', Operator::OP_NE, -1),
                ];
                if (!empty($patient_id)) $patientcheckdataWhere['where']['patient_id'] = StringHelper::toArray($patient_id);
                $patientcheckdataWhere['columns'] = ['id', 'patient_id', 'checktime_id', 'form_id', 'is_yc', 'data'];
                $patientcheckDatas = $this->LocalService()->patientFormContent->fetchAll($patientcheckdataWhere);

                //查询备注说明字段
                $fieldWhere['where'] = [
                    'is_del' => 0,
                    'item_id' => $item_id,
                    'var_name' => ['CHECKREMARK', 'CHRE', 'OUTPLANCHECK', 'OPCH', 'ISCHECK'],
                ];
                $fieldWhere['columns'] = ['form_id', 'id','var_name'];
                $fieldDatas = $this->LocalService()->itemFormField->fetchAll($fieldWhere);
                $checkremarkArr = []; //备注
                $outplancheckArr = [];//计划外
                $ischeck = [];//已开具/不检查
                foreach ($fieldDatas as $fieldK => $fieldV) {
                    if($fieldV['var_name'] == 'CHECKREMARK' || $fieldV['var_name'] == 'CHRE'){
                        $checkremarkArr[$fieldV['form_id']] = $fieldV['id'];
                    }elseif($fieldV['var_name'] == 'OUTPLANCHECK' || $fieldV['var_name'] == 'OPCH'){
                        $outplancheckArr[$fieldV['form_id']] = $fieldV['id'];
                    }else{
                        $ischeck[$fieldV['form_id']] = $fieldV['id'];
                    }
                }

                $patientplancheck = []; //计划外
                $patientcheckIsyc = []; //是否填写备注
                $checkType = []; //开具类型
                if (!empty($patientcheckDatas)) {
                    foreach ($patientcheckDatas as $pcdK => $pcdV) {

                        $jsonData = json_decode($pcdV['data'], true);
                        if (!empty($jsonData[$outplancheckArr[$pcdV['form_id']]]) && $jsonData[$outplancheckArr[$pcdV['form_id']]] != '[]') {
                            $patientplancheck[$pcdV['patient_id']][$pcdV['checktime_id']][$pcdV['form_id']] = '有';
                        }
                        if (!empty($jsonData[$checkremarkArr[$pcdV['form_id']]])) {
                            $patientcheckIsyc[$pcdV['patient_id']][$pcdV['checktime_id']][$pcdV['form_id']] = $jsonData[$checkremarkArr[$pcdV['form_id']]];
                        } else {
                            $patientcheckIsyc[$pcdV['patient_id']][$pcdV['checktime_id']][$pcdV['form_id']] = '';
                        }

                        if(!empty($jsonData[$ischeck[$pcdV['form_id']]])){
                            $checkType[$pcdV['patient_id']][$pcdV['checktime_id']][$pcdV['form_id']] = $jsonData[$ischeck[$pcdV['form_id']]];
                        }
                    }
                }

                //三层结构 受试者、检查点、表单

                //抓取CS缓存文件数据 循环检查项分类
                foreach ($formDatas as $cateKk => $cateV) {

                    $cateK = $cateV['checklist_id'];
                    $catalogue[99 + $cateK][] = $cateV['name'];
                    $catalogue[99 + $cateK][] = $cateV['var_name'];
                    //表头
                    $data = [
                        ['INVSITE', 'PT', 'SUBNAM', 'CPEVENT', 'FORM_SEQ', 'LBYN', $fieldDatas[0]['var_name'], 'LBDAT_'],
                        ['中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '开具医嘱/化验单', '备注说明', '采集日期']
                    ];
//                    $tmp = [
//                        ['INVSITE', 'PT', 'SUBNAM', 'CPEVENT', 'FORM_SEQ', 'LBYN', $fieldDatas[0]['var_name'], 'LBDAT_'],
//                        ['中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '开具医嘱/化验单', '备注说明', '采集日期','指标名称','结果','范围值','单位','临床评估']
//                    ];
                    $remainder = 0;
                    if (empty($attrnumber)) {
                        unset($data[0][1], $data[1][1]);
                        $remainder += 1;
                    }
                    if (empty($attrname)) {
                        unset($data[0][2], $data[1][2]);
                        $remainder += 1;
                    }
                    $data[0] = array_values($data[0]);
                    $data[1] = array_values($data[1]);

                    //检查项表头
                    foreach ($checknameDatas[$cateK] as $k => $v) {
                        if (strstr($v['variable'], '_') != false) {
                            $variable = substr($v['variable'], strripos($v['variable'], "_") + 1);
                        } else {
                            $variable = $v['variable'];
                        }
                        if ($cateV['group_id'] != 8) {
                            //变量名
                            $data[0][] = $v['variable'];
                            $data[1][] = $v['name'];
                            //测量结果
                            $data[0][] = "LBORRES" . '_' . $variable;
                            $data[1][] = $v['name'] . "测量结果";
                            //取值范围
                            $data[0][] = "LBORNR" . '_' . $variable;
                            $data[1][] = $v['name'] . "取值范围";
                            //单位
                            $data[0][] = "LBORRESU" . '_' . $variable;
                            $data[1][] = $v['name'] . "计数单位";
                            //范围下限
//                            $data[0][] = "LBORNRLO" . '_' . $variable;
//                            $data[1][] = "正常范围下限" . '-' . $v['name'];
//                            //范围上限
//                            $data[0][] = "LBORNRHI" . '_' . $variable;
//                            $data[1][] = "正常范围上限" . '-' . $v['name'];
                            //临床评估
                            $data[0][] = "LBCLSIG" . '_' . $variable;
                            $data[1][] = "临床评估" . '-' . $v['name'];
                        }
                    }

                    if ($cateV['group_id'] == 8) {
                        $data[0][] = '';
                        $data[1][] = '医嘱内容';
                        $data[0][] = '';
                        $data[1][] = '开始时间';
                        $data[0][] = '';
                        $data[1][] = '执行时间/结束时间';
                    }

                    if(isset($OPCHDatas[$cateV['id']])){
                        $data[0][] = $fieldDatas[0]['var_name'];
                        $data[1][] = "计划外检查";
                    }

                    $DateFormat = $this->LocalService()->itemCheckdate->getDateType($item_id);
                    $dataKey = 2;
//                    $kkk = 2;
                    //中心
                    foreach ($itemsignatoryDatas as $key => $val) {
                        //循环受试者
                        foreach ($patientDatas[$val['value']] as $patientK => $patientV) {

                            if ($cateV['group_id'] == 8) {
                                //循环中心获取中心缓存文件数据
                                $applyfilepath = APP_PATH . '/data/itemIdentificationResult/' . $item_id . '/' . $val['value'] . '/' . $item_id . '-' . $val['value'] . '-' . $patientV['id'] . '-8' . '.txt';
                            } else {
                                //循环中心获取中心缓存文件数据
                                $applyfilepath = APP_PATH . '/data/itemIdentificationResult/' . $item_id . '/' . $val['value'] . '/' . $item_id . '-' . $val['value'] . '-' . $patientV['id'] . '.txt';
                            }

                            //数据集
                            $result = json_decode(file_get_contents($applyfilepath, 0), true);


                            //循环检查点
                            foreach ($checktimeDatas as $checkK => $checkV) {


                                if ($checkV['order'] > $checktimeDatas[$patientchecktimeIndex[$patientV['id']]]['order'] && $checktimeDatas[$patientchecktimeIndex[$patientV['id']]]['is_isolate'] == 0) continue;

                                if ($cateV['group_id'] != 8 && $randomDatas[$checkV['random_id']] != 0 && $checkV['is_del'] != 9 && !empty($patientV['random_id']) && !empty($checkV['random_id']) && ($patientV['random_id'] != $checkV['random_id'])) {
                                    continue;
                                }
                                // 检查点 --分类 --指标 数据不存在 退出
                                if ($checkV['is_del'] == 9 && ($patientV['patient_status'] != 3 || $patientV['patient_status'] != 4)) continue;

                                if (!isset($contentArr[$checkV['id']][$cateV['id']]) && $checkV['is_del'] != 9) {
                                    continue;
                                }

                                //OCR(遗嘱)
                                if ($cateV['group_id'] == 8) {

                                    foreach ($result[$checkV['id']][$cateV['id']] as $kk => $vv) {
                                        // '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '是否完成', '采集日期'
                                        $data[$dataKey][] = $val['number'];
                                        //筛选号
                                        if (!empty($attrnumber)) $data[$dataKey][] = $patientV['patient_number'];
                                        //受试者姓名
                                        if (!empty($attrname)) $data[$dataKey][] = $patientV['patient_name'];
                                        //访视名称
                                        $data[$dataKey][] = $StageDatas[$checkV['stage_id']]['stage_name'] . '-' . $checkV['check_name'];
                                        //表单序号
                                        $data[$dataKey][] = 1;
                                        //开具医嘱/化验单
                                        $data[$dataKey][] = ($checkType[$patientV['id']][$checkV['id']][$cateV['id']] == 2) ? '已开具' : '不检查';
                                        //备注说明
                                        if (isset($patientcheckIsyc[$patientV['id']][$checkV['id']][$cateV['id']])) {
                                            //取表单填写的数据
                                            $data[$dataKey][] = $patientcheckIsyc[$patientV['id']][$checkV['id']][$cateV['id']];
                                        } else {
                                            $data[$dataKey][] = '';
                                        }
                                        //采集日期
                                        $data[$dataKey][] = '';

                                        $data[$dataKey][] = trim($vv['result']);
                                        $data[$dataKey][] = !empty($vv['start_time']) ? date('Y-m-d : H:i:s', $vv['start_time']) : '';
                                        $data[$dataKey][] = !empty($vv['start_time']) ? date('Y-m-d : H:i:s', $vv['stop_time']) : '';
                                        if(isset($OPCHDatas[$cateV['id']])){
                                            //计划外检查
                                            if (isset($patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']])) {
                                                $data[$dataKey][12-(1+$remainder)] = $patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']];
                                            }
                                        }

                                        ++$dataKey;
                                    }
                                } else {
                                    //未填写、未开具、未填写备注、未填写计划外检查
                                    if(empty($result[$checkV['id']][$cateV['id']]) && (
                                            !isset($patientcheckIsyc[$patientV['id']][$checkV['id']][$cateV['id']])
                                            &&
                                            !isset($checkType[$patientV['id']][$checkV['id']][$cateV['id']])
                                            &&
                                            !isset($patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']])
                                        )) continue;

                                    // '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '是否完成', '采集日期'
                                    $data[$dataKey][] = $val['number'];
                                    //筛选号
                                    if (!empty($attrnumber)) $data[$dataKey][] = $patientV['patient_number'];
                                    //受试者姓名
                                    if (!empty($attrname)) $data[$dataKey][] = $patientV['patient_name'];
                                    //访视名称
                                    $data[$dataKey][] = $StageDatas[$checkV['stage_id']]['stage_name'] . '-' . $checkV['check_name'];
                                    //表单序号
                                    $data[$dataKey][] = 1;
                                    //开具医嘱/化验单
                                    $data[$dataKey][] = ($checkType[$patientV['id']][$checkV['id']][$cateV['id']] == 2) ? '已开具' : '不检查';
                                    //备注说明
                                    if (isset($patientcheckIsyc[$patientV['id']][$checkV['id']][$cateV['id']])) {
                                        //取表单填写的数据
                                        $data[$dataKey][] = $patientcheckIsyc[$patientV['id']][$checkV['id']][$cateV['id']];
                                    } else {
                                        $data[$dataKey][] = '';
                                    }
                                    //采集日期
                                    $data[$dataKey][] = '';
//                                    //计划外检查
//                                    if (isset($patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']])) {
//                                        $data[$dataKey][(count($checknameDatas[$cateK]) * 6) + (8 - $remainder)] = $patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']];
//                                    } else {
//                                        $data[$dataKey][(count($checknameDatas[$cateK]) * 6) + (8 - $remainder)] = '无';
//                                    }

                                    //未识别表单，直接退出
                                    if (empty($result[$checkV['id']][$cateV['id']])) {
                                        if (isset($patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']])) {
                                            $data[$dataKey][(count($checknameDatas[$cateK]) * 5) + (8 - $remainder)] = $patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']];
                                        } else {
                                            $data[$dataKey][(count($checknameDatas[$cateK]) * 5) + (8 - $remainder)] = '无';
                                        }
                                        ++$dataKey;continue;
                                    }


                                    //循环项目中检查项设置
                                    foreach ($checknameDatas[$cateK] as $checknameK => $checknameV) {
                                        //是否匹配成功开关，如果未匹配成功则录入空
                                        $falg = 0;
                                        //循环用户填写的检查项内容
                                        foreach ($result[$checkV['id']][$cateV['id']] as $kk => $vv) {
                                            if ($checknameV['checkname_id'] == $vv['checkname_id'] || $checknameV['name'] == $vv['item_name']) {
                                                //更新采集时间
                                                if (empty($data[$dataKey][7 - $remainder]) && !empty($vv['collect_date']))
                                                    $data[$dataKey][7 - $remainder] = $vv['collect_date'];
                                                $falg = 1;

                                                //指标名称
                                                $data[$dataKey][] = $vv['item_name'];

                                                //测量结果
                                                $data[$dataKey][] = trim($vv['result']);
                                                //取值范围
                                                if($vv['item_min_val'] != '' && $vv['item_max_val'] != ''){
                                                    $data[$dataKey][] = $vv['min_symbol'].$vv['item_min_val'].'~'.$vv['max_symbol'].$vv['item_max_val'];
                                                }elseif(!empty($vv['item_max_val']) && $vv['item_max_val'] != ''){
                                                    $data[$dataKey][] = $vv['max_symbol'].$vv['item_max_val'];
                                                }elseif(!empty($vv['item_min_val']) && $vv['item_min_val'] != ''){
                                                    $data[$dataKey][] = $vv['min_symbol'].$vv['item_min_val'];
                                                }else{
                                                    $data[$dataKey][]  = '';
                                                }


                                                //单位
                                                $data[$dataKey][] = trim($vv['unit'], ' ');
                                                //临床评估 0为未选中 ，1为正常 2为cs 3为ncs
                                                if ($vv['is_normal_type'] == 0)
                                                    $ClinicalEvaluation = '';
                                                else if ($vv['is_normal_type'] == 1)
                                                    $ClinicalEvaluation = '正常';
                                                else if ($vv['is_normal_type'] == 2)
                                                    $ClinicalEvaluation = 'CS';
                                                else if ($vv['is_normal_type'] == 3)
                                                    $ClinicalEvaluation = 'NCS';
                                                $data[$dataKey][] = $ClinicalEvaluation;
                                                break;
                                            }

                                        }
                                        if ($falg == 0) {
                                            $data[$dataKey][] = $checknameV['name'];
                                            $data[$dataKey][] = '';
                                            $data[$dataKey][] = '';
                                            $data[$dataKey][] = $checknameV['unit'];
                                            $data[$dataKey][] = '未查';
                                        }
                                    }
                                    if(isset($OPCHDatas[$cateV['id']])){
                                        //计划外检查
                                        if (isset($patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']])) {
                                            $data[$dataKey][(count($checknameDatas[$cateK]) * 5) + (8 - $remainder)] = $patientplancheck[$patientV['id']][$checkV['id']][$cateV['id']];
                                        } else {
                                            $data[$dataKey][(count($checknameDatas[$cateK]) * 5) + (8 - $remainder)] = '无';
                                        }
                                    }

                                    ++$dataKey;
                                }
                            }
                        }
                    }
                    //将数据存入数组
                    $formname = str_replace("/", '-', $cateV['name']);
                    $formname = str_replace("[", '【', $formname);
                    $formname = str_replace("]", '】', $formname);
                    $formname = str_replace("？", '', $formname);
                    $formname = str_replace("（", '【', $formname);
                    $formname = str_replace("）", '】', $formname);
                    $formname = str_replace(" ", '', $formname);

                    $formData[$formname] = $data;
                }
            }
        }
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] . '-' . $create_time . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header(['表单名称', '表单变量名'])->data($catalogue);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //循环指标数据生成sheet
        foreach ($formData as $k => $v) {
            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }
            $fileObject->addSheet($sheetName)->data($formData[$k]);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }

        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes :导出项目检查项变量名
     * @param $item_id
     * @throws \Exception
     * Author:lwl
     * Date:2022/8/3 14:13
     */
    public function csVariable($exportdata)
    {
        $item_id = $exportdata['item_id'] ?: 0;       //项目ID
        //获取当前项目下符合条件的检
        //查分类以及检查项
        $checknameData = $this->getItemcheckname($item_id);

        //检查项分类
        $categoryDatas = $checknameData['categoryDatas'];

        //检查项
        $checknameDatas = $checknameData['checknameDatas'];

        $varData = [];
        $catalogue = [];
        $categoryKey = 1;
        foreach ($categoryDatas as $key => $value) {
            $catalogue[$categoryKey][] = $value['category_name'];
            $catalogue[$categoryKey][] = $value['category_variable'];
            $categoryKey++;
            //表头
            $data = [['指标名称', '指标变量名', '测量结果变量名', '计数单位变量名', '正常范围下限变量名', '正常范围上限变量名', '临床评估变量名']];

            foreach ($checknameDatas[$key] as $k => $v) {
                $checknameKey = 1 + $k;
                if (strstr($v['variable'], '_') != false)
                    $variable = substr($v['variable'], strripos($v['variable'], "_") + 1);
                else
                    $variable = $v['variable'];

                //变量名
                $data[$checknameKey][] = $v['name'];
                $data[$checknameKey][] = $v['variable'];
                //测量结果/
                $data[$checknameKey][] = "LBORRES" . '_' . $variable;
//                $data[$checknameKey][] = $v['name'] . "测量结果";
                //1整数2一位小数3两位小数4三位小数5文本
                //单位
                $data[$checknameKey][] = "LBORRESU" . '_' . $variable;
//                    $data[$checknameKey][] = $v['name'] . "计数单位";
                //范围下限
                $data[$checknameKey][] = "LBORNRLO" . '_' . $variable;
//                    $data[$checknameKey][] = "正常范围下限" . '-' . $v['name'];
                //范围上限
                $data[$checknameKey][] = "LBORNRHI" . '_' . $variable;
//                    $data[$checknameKey][] = "正常范围上限" . '-' . $v['name'];
//                if ($v['check_type'] != 5) {
//
//                } else {
//                    $data[$checknameKey][] = '';
//                    //范围下限
//                    $data[$checknameKey][] = '';
//                    //范围上限
//                    $data[$checknameKey][] = '';
//                }
                //临床评估
                $data[$checknameKey][] = "LBCLSIG" . '_' . $variable;
//                $data[$checknameKey][] = "临床评估" . '-' . $v['name'];
            }
            $varData[$value['category_name']] = $data;

        }

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        $fileName = $itemInfo['name'] . '化验类表单变量-' . $exportdata['create_time'] . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $fileObject->header(['化验单名称', '化验单变量名'])->data($catalogue);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //循环指标数据生成sheet
        foreach ($varData as $k => $v) {
            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }
            $formname = str_replace("、", '-', $sheetName);
            $formname = str_replace("/", '-', $formname);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);
            $fileObject->addSheet($formname)->data($varData[$k]);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }
        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes :导出项目表单变量名
     * @param $formdata
     * Author:唐伯虎不虎
     * Date:2022/8/10 9:26
     */
    public function formVariable($formdata)
    {

        $item_id = $formdata['item_id'] ?: 0;       //项目ID

        //获取表单
        $formDatas = $this->getform($item_id, 0);

        //获取表单字段
        $formfieldDatas = $this->getformrules($item_id, 0);

        $formfieldoptions = $this->getformoptions($item_id, 0, 1);


        $varData = [];
        $catalogue = [];
        $categoryKey = 1;
        foreach ($formDatas as $key => $value) {
            $catalogue[$categoryKey][] = $value['name'];
            $catalogue[$categoryKey][] = $value['var_name'];
            $categoryKey++;
            //表头
            $data = [['表单内容', '表单内容变量名']];
            $num = 1;
            if (!empty($formfieldDatas[$key]['var_name'])) {
                foreach ($formfieldDatas[$key]['var_name'] as $k => $v) {
                    $checknameKey = $num + $k;
                    //变量名
                    $data[$checknameKey][] = $formfieldDatas[$key]['name'][$k];
                    $data[$checknameKey][] = $v;

                    if (isset($formfieldoptions[$formfieldDatas[$key]['data'][$k]['id']])) {
                        foreach ($formfieldoptions[$formfieldDatas[$key]['data'][$k]['id']] as $kk => $vv) {
                            ++$num;
                            $checknameKey = $num + $k;
                            $data[$checknameKey][] = '';
                            $data[$checknameKey][] = $vv['name'];
                            $data[$checknameKey][] = $vv['var_name'];
                        }
                    }
                }
            }
            $varData[$value['name']] = $data;
        }

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        $fileName = $itemInfo['name'] . '表单变量-' . $formdata['create_time'] . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');
        $fileObject->header(['表单名称', '表单变量名'])->data($catalogue);

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        $excelObj = new Excel([
            'path' => $_SERVER['DOCUMENT_ROOT'] . '/download/'
        ]);


        //循环指标数据生成sheet
        foreach ($varData as $k => $v) {
            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }
            $formname = str_replace("、", '-', $sheetName);
            $formname = str_replace("/", '-', $formname);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);
            $fileObject->addSheet($formname)->data($varData[$k]);
//->freezePanes(1, 6)
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }
        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes : 受试者详细报告导出(横表)
     * Author:lwl
     * Date:2022/8/8 13:41
     */
    public function patientformreport($data)
    {
        $item_id = $data['item_id'] ?: '0';
        $itemsig_id = $data['itemsig_ids'] ?: '';
        $patient_status = $data['patient_status'] ?: '10';
        $patient_ids = $data['patient_ids'];
        $complete_type = explode(',',$data['complete_type']);

        if (empty($item_id)) {
            return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');
        }

        //配置导出
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        //受试者信息
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_ids, $patient_status);

        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称


        //中心信息
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        $signDatas = [];
        foreach ($itemsignatoryDatas as $k => $v) {
            $signDatas[$v['value']] = $v['number'];
        }
        unset($itemsignatoryDatas);

        //查询项目检查点
        $checktimeWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checktimeWhere['columns'] = ['id', 'check_name', 'stage_id', 'random_id','check_order','is_isolate'];
        $checktimeWhere['order'] = 'check_order';
        $checktimeDatas = $this->LocalService()->itemChecktime->fetchAll($checktimeWhere);
        unset($checktimeWhere);

        //查询表单
        $formWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $formWhere['columns'] = ['id', 'name', 'group_id','gco_pool','info_collect_type'];
        $formWhere['order'] = 'order';
        $formDatas = $this->LocalService()->itemForm->fetchAll($formWhere);
        unset($formWhere);

        $form = [];
        $poolForm = [];
        $pool = [];
        foreach ($formDatas as $k => $v) {
            $form[$v['id']] = $v;
            if($v['gco_pool'] != '') {
                $poolForm[] = $v['id'];
                $pool[$v['gco_pool']][] = $v['id'];
            }
        }
        unset($formDatas);

        //共享图片
        $patientformcontentImg = [];
        if(!empty($poolForm)){
            $contentImg = $this->LocalService()->patientFormContentImg->fetchAll([
                'where'=> [
                    'is_del' => 0,
                    'item_id' => $item_id,
                    'form_id' => $poolForm,
                ],
                'columns'=>['id','checktime_id','form_id','patient_id'],
                'group'=>['patient_id','checktime_id','form_id']
            ]);
            foreach($contentImg as $key=>$value){
                $patientformcontentImg[$value['patient_id']][$value['checktime_id']][$value['form_id']] = $value['id'];
            }
            unset($contentImg);
        }

        //查询当前检查点表单设置
        $checkcontentWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checkcontentWhere['columns'] = ['id', 'form_id', 'check_id','associated_ishide'];
        $checkcontentWhere['order'] = 'order';
        $checkcontent = $this->LocalService()->itemCheckcontent->fetchAll($checkcontentWhere);
        $checkcontentDatas = [];
        $useFormArr = [];
        foreach($checkcontent as $k=>$v){
            $useFormArr[] = $v['form_id'];
            $checkcontentDatas[$v['check_id']][] = $v;
        }

        unset($checkcontentWhere,$checkcontent);

        //查询受试者表单、化验单是否完成 patienrform
        $patientformWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($itemsig_id)) $patientformWhere['where']['itemsig_id'] = StringHelper::toArray($itemsig_id);
        if(!empty($patient_ids)) $patientformWhere['where']['patient_id'] = StringHelper::toArray($patient_ids);
        $patientformWhere['columns'] = ['id', 'patient_id', 'checktime_id', 'form_id', 'is_complete'];
        $patientformDatas = $this->LocalService()->patientForm->fetchAll($patientformWhere);

        $patientform = [];
        foreach ($patientformDatas as $k => $v) {
            $patientform[$v['patient_id'] . '-' . $v['checktime_id'] . '-' . $v['form_id']] = $v;
        }

        unset($patientformWhere,$patientformDatas);

//        查询受试者表单、化验单是否完成 patienrformcontent
        $patientformContentWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($itemsig_id)) $patientformContentWhere['where']['itemsig_id'] = StringHelper::toArray($itemsig_id);
        if(!empty($patient_ids)) $patientformContentWhere['where']['patient_id'] = StringHelper::toArray($patient_ids);
        $patientformContentWhere['columns'] = ['id', 'patient_id', 'checktime_id', 'form_id', 'is_yc'];
        $patientformcontentDatas = $this->LocalService()->patientFormContent->fetchAll($patientformContentWhere);
        $patientformcontent = [];
        foreach ($patientformcontentDatas as $k => $v) {
            $patientformcontent[$v['patient_id'] . '-' . $v['checktime_id'] . '-' . $v['form_id']] = $v;
        }
        unset($patientformcontentDatas);

        //查询项目详情
        $iteminfoWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $iteminfoWhere['columns'] = ['id', 'name'];
        $iteminfo = $this->LocalService()->itemInfo->fetchOne($iteminfoWhere);

        //随机方案
        $randomWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $randomWhere['columns'] = ['id', 'random_name', 'type'];
        $randomData = $this->LocalService()->itemRandom->fetchAll($randomWhere);
        $randomDatas = [];
        foreach ($randomData as $k => $v) {
            $randomDatas[$v['id']] = $v;
        }
        unset($randomWhere,$randomData);

        $fileName = $iteminfo['name'] . "受试者进度详细报告(横表)" . '-' . $data['create_time'] . '.xlsx';

        $fileObject = $xlsxObject->fileName($fileName, '符号定义');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();


        $symbol_define = [
            ['√','已完成'],
            ['X','不检查'],
            ['?','表单未填写、未填写完或者已开具未传图，颜色为橙色或红色'],
            ['--','不需要填写的表单 如：未触发关联的表单'],
            ['(注：住院医嘱/出院医嘱，有传图 √      未传图 ?)',''],
        ];
        $fileObject->header(['符号', '定义'])->data($symbol_define);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);


        $formlist = [];

        $stageDatas = $this->getItemstage($item_id);
        $formlist[0][] = '阶段';
        $formlist[0][] = '检查点';
        foreach ($checktimeDatas as $k => $v) {
            $formlist[$k+1][] = $stageDatas[$v['stage_id']]['stage_name'];
            $formlist[$k+1][] = $randomDatas[$v['random_id']]['random_name'] . '-' . $v['check_name'];
        }
        //ECRF表单

        $fileObject->addSheet('eCRF表单')->data($formlist);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //-------------------------------------------------------------------------------------------------------------
        $associated_ishide = [];
        foreach($checkcontentDatas as $k=>$v){
            if($v['associated_ishide'] == 1){
                $associated_ishide[] = $v['form_id'];
            }
        }

        //查询当前表单是不是为二级 如果是 查询一级表单是否做过 未做过不显示
        $FormRelationwhere['where'] = [
            'is_del' => 0,
            'relation_form_id' => array_unique($useFormArr)
        ];
        if(!empty($associated_ishide)){
            $FormRelationwhere['where'][] = new NotIn('relation_form_id', $associated_ishide);
            unset($associated_ishide);
        }
        $FormRelationwhere['columns'] = ['form_id','relation_form_id'];
        $FormRelationDatas=$this->LocalService()->itemFormRelation->fetchAll($FormRelationwhere);

        $FormRelationDatas_handle = [];
        foreach($FormRelationDatas as $k=>$v){
            $FormRelationDatas_handle[$v['relation_form_id']] = $v;
        }
        unset($FormRelationDatas,$FormRelationwhere);


        $patientchecktimeFormWhere = [
            'item_id'=>$item_id,
            'is_del'=>0
        ];

        if(!empty($itemsig_id)){
            $patientchecktimeFormWhere['itemsig_id'] = StringHelper::toArray($itemsig_id);
        }
        $PatientformInfo = $this->LocalService()->itemPatientChecktimeForm->fetchAll([
            'where'=> $patientchecktimeFormWhere
        ]);

        $PatientformInfo_handle = [];
        foreach($PatientformInfo as $isshowK=>$isshowV){
            $PatientformInfo_handle[$isshowV['patient_id'].'-'.$isshowV['checktime_id'].'-'.$isshowV['form_id']] = $isshowV;
        }

        unset($PatientformInfo);

        //-------------------------------------------------------------------------------------------------------------

        //获取受试者当前检查点排序值
        $patientchecktimeWhere = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        if(!empty($itemsig_id)) $patientchecktimeWhere['itemsig_id'] = explode(',', $itemsig_id);
        if(!empty($patient_ids)) $patientchecktimeWhere['patient_id'] = explode(',', $patient_ids);
        $patientchecktimeData = $this->LocalService()->itemPatientchecktime->fetchAll([
            'where'=>$patientchecktimeWhere,
            'columns'=>['id','patient_id','check_order','checktime_id','anchor_id','is_now_state','leave_type'],
            'order'=>['patient_id','check_order']
        ]);
        unset($patientchecktimeWhere);

        $tmp = [];
        $tmpPatient = [];
        $patientchecktimeHandle = [];
        foreach($patientchecktimeData as $key=>$value){
            if($value['is_now_state'] == 0 && !isset($tmpPatient[$value['patient_id']])) {
                $tmp[$value['patient_id']][$value['anchor_id']] = $value['anchor_id'];
                unset($patientchecktimeData[$key]);
                continue;
            }else{
                if(($value['is_now_state'] == 1 || $value['leave_type'] != '') && !isset($tmpPatient[$value['patient_id']])){
                    $tmpPatient[$value['patient_id']] = $value;
                    unset($patientchecktimeData[$key]);
                }else{
                    if($tmpPatient[$value['patient_id']]['anchor_id'] != $value['anchor_id'] && !isset($tmp[$value['patient_id']][$value['anchor_id']]) ){
                        $patientchecktimeHandle[$value['patient_id']][$value['checktime_id']] = $value;
                    }elseif($tmpPatient[$value['patient_id']]['anchor_id'] == $value['anchor_id']){
                        $patientchecktimeHandle[$value['patient_id']][$value['checktime_id']] = $value;
                    }
                }
            }
        }
        unset($patientchecktimeData);

        $summary = [];

        foreach ($checktimeDatas as $k => $v) {
            $data = [];
            $arr = ['中心编号', '受试者筛选号', '受试者姓名', '表单完成数量'];
            foreach ($checkcontentDatas[$v['id']] as $key => $value) {
                if (isset($form[$value['form_id']])) {
                    $arr[] = $form[$value['form_id']]['name'];
                }
            }
            $data[] = $arr;
            $kk = 0;
            //循环受试者 查询受试者表单填写状态
            foreach ($signDatas as $signk => $signv) {
                foreach ($patientDatas[$signk] as $key => $vv) {
                    if (!isset($summary[$vv['id']][$v['id']])) {
                        $summary[$vv['id']][$v['id']] = 0;
                    }
                    $kk++;
                    //随机分组
                    if ($randomDatas[$v['random_id']]['type'] == 2) {
                        if ($vv['random_id'] != $v['random_id']) continue;
                    }
                    //已完成表单数量
                    foreach ($checkcontentDatas[$v['id']] as $kd => $vd) {

                        if (!isset($form[$vd['form_id']])) continue;

                        if(isset($patientchecktimeHandle[$vv['id']][$v['id']]) && $v['is_isolate'] == 0){
                            $summary[$vv['id']][$v['id']] = '';
                            continue;
                        }

                        if(in_array($form[$vd['form_id']]['info_collect_type'],['2','3']) && isset($form[$vd['form_id']]['gco_pool']) && isset($pool[$form[$vd['form_id']]['gco_pool']])){
                            //获取到一组的表单ID
                            $flag = false;
                            foreach($pool[$form[$vd['form_id']]['gco_pool']] as $poolK => $poolV){
                                if(isset($patientformcontentImg[$vv['id']][$v['id']][$poolV])){
                                    $summary[$vv['id']][$v['id']] += 1;
                                    $flag = true;
                                    break;
                                }
                            }
                            if($flag == true) {
                                continue;
                            }

                        }

                        $patientformcomplete = isset($patientform[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_complete']) ? $patientform[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_complete'] : '9';
                        if ($patientformcomplete == 0) {
                            continue;
                        } elseif ($patientformcomplete == 1) {
                            if(isset($FormRelationDatas_handle[$vd['form_id']]) && !isset($PatientformInfo_handle[$vv['id'].'-'.$v['id'].'-'.$vd['form_id']])){
                                if(in_array(3,$complete_type)) $summary[$vv['id']][$v['id']] += 1;
                            }else{

                                if ($patientformcontent[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_yc'] == '-1' && $form[$vd['form_id']]['group_id'] == 7) {
                                    continue;
                                } elseif ($form[$vd['form_id']]['group_id'] == 7 && $patientformcontent[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_yc'] == 0) {
                                    if(in_array(2,$complete_type)) $summary[$vv['id']][$v['id']] += 1;
                                } else {
                                    if(in_array(1,$complete_type)) $summary[$vv['id']][$v['id']] += 1;
                                }
                            }
                        } elseif ($patientformcomplete == 9) {

                            if(isset($FormRelationDatas_handle[$vd['form_id']])){

                                if(in_array(3,$complete_type)) $summary[$vv['id']][$v['id']] += 1;
                            }else{
                                continue;
                            }
                        }
                    }
                }
            }
        }

        $gather = [];
        foreach ($randomDatas as $k => $v) {
            $headerdata = [];
            $headerarr = ['中心编号'];
            if (!empty($attrnumber))  $headerarr[]    = '筛受试者筛选号';
            if (!empty($attrname)) $headerarr[]    = '受试者姓名';
            $headerarr[] = '受试者状态';

            foreach ($checktimeDatas as $key => $value) {
                if ($value['random_id'] != $v['id']) continue;
                $headerarr[] = $value['check_name'];
            }
            $headerdata[] = $headerarr;
            $kk = 0;

            $headerdata[$kk + 1][] = '';
            if (!empty($attrnumber)) {
                $headerdata[$kk + 1][] = '';
            }
            if (!empty($attrname)) {
                $headerdata[$kk + 1][] = '';
            }
            $headerdata[$kk + 1][] = '应填表单数量';
            foreach ($checktimeDatas as $kc => $vc) {
                if ($vc['random_id'] != $v['id']) continue;
                foreach ($checkcontentDatas[$vc['id']] as $kd => $vd) {
                    if (!isset($form[$vd['form_id']])) {
                        unset($checkcontentDatas[$vc['id']][$kd]);
                    }
                }
                $headerdata[$kk + 1][] = count($checkcontentDatas[$vc['id']]);
            }
            foreach ($signDatas as $signk => $signv) {

                foreach ($patientDatas[$signk] as $key => $vv) {
                    if ($vv['random_id'] == '' || $vv['random_id'] == NULL) $vv['random_id'] = 0;
                    //随机分组
                    if ($randomDatas[$v['id']]['type'] == 2) {
                        if ($vv['random_id'] != $v['id']) continue;
                    }
                    $kk++;
                    $headerdata[$kk + 1][] = $signv;
                    if (!empty($attrnumber)) {
                        $headerdata[$kk + 1][] = $vv['patient_number'];
                    }
                    if (!empty($attrname)) {
                        $headerdata[$kk + 1][] = $vv['patient_name'];
                    }

                    $headerdata[$kk + 1][] = $this->getpatientStatus(0, $vv['patient_status']);
                    foreach ($checktimeDatas as $kc => $vc) {
                        if ($vc['random_id'] != $v['id']) continue;
                        $headerdata[$kk + 1][] = $summary[$vv['id']][$vc['id']];
                    }
                }
            }
            $gather[$v['id']] = $headerdata;
        }
        if (!empty($gather)) {
            foreach ($gather as $k => $v) {
                $sheetName = $randomDatas[$k]['random_name'] . '-' . '汇总表单';
                $name = str_replace("/", '-', $sheetName);
                $fileObject->addSheet($name)->data($v);
                $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
            }
            unset($summary);
        }

        foreach ($checktimeDatas as $k => $v) {
            $data = [];
            $arr = ['中心编号'];
            if (!empty($attrnumber)) $arr[]    = '受试者筛选号';
            if (!empty($attrname)) $arr[]    = '受试者姓名';
            $arr[] = '表单完成数量';
            $indexK = count($arr)-1;

            foreach ($checkcontentDatas[$v['id']] as $key => $value) {
                if (isset($form[$value['form_id']])) {
                    $arr[] = $form[$value['form_id']]['name'];
                }
            }
            $data[] = $arr;
            $kk = 0;
            //循环受试者 查询受试者表单填写状态
            foreach ($signDatas as $signk => $signv) {

                foreach ($patientDatas[$signk] as $key => $vv) {
                    if ($vv['random_id'] == '' || $vv['random_id'] == NULL) $vv['random_id'] = 0;
                    //随机分组
                    if ($randomDatas[$v['random_id']]['type'] == 2) {
                        if ($vv['random_id'] != $v['random_id']) continue;
                    }
                    $kk++;
                    $data[$kk + 1][] = $signv;
                    if (!empty($attrnumber)) {
                        $data[$kk + 1][] = $vv['patient_number'];
                    }
                    if (!empty($attrname)) {
                        $data[$kk + 1][] = $vv['patient_name'];
                    }

                    $data[$kk + 1][] = 0;
                    //已完成表单数量
                    $complete = 0;
                    foreach ($checkcontentDatas[$v['id']] as $kd => $vd) {

                        if (!isset($form[$vd['form_id']])) continue;

                        if(isset($patientchecktimeHandle[$vv['id']][$v['id']]) && $v['is_isolate'] == 0){
//                            $summary[$vv['id']][$v['id']] = '';
                            continue;
                        }
                        if(in_array($form[$vd['form_id']]['info_collect_type'],['2','3']) && isset($form[$vd['form_id']]['gco_pool']) && isset($pool[$form[$vd['form_id']]['gco_pool']])){
                            //获取到一组的表单ID
                            $flag = false;
                            foreach($pool[$form[$vd['form_id']]['gco_pool']] as $poolK => $poolV){
                                if(isset($patientformcontentImg[$vv['id']][$v['id']][$poolV])){
                                    $data[$kk + 1][] = '√';
                                    if(in_array(1,$complete_type)) $data[$kk + 1][$indexK] += 1;
                                    $flag = true;
                                    break;
                                }
                            }
                            if($flag == true) {
                                continue;
                            }

                        }

                        $patientformcomplete = isset($patientform[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_complete']) ? $patientform[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_complete'] : '9';


                        if ($patientformcomplete == 0) {
                            if(isset($FormRelationDatas_handle[$vd['form_id']]) && !isset($PatientformInfo_handle[$vv['id'].'-'.$v['id'].'-'.$vd['form_id']])){
                                $data[$kk + 1][] = '--';
                                if(in_array(3,$complete_type)) $data[$kk + 1][$indexK] += 1;
                            }else{
                                $data[$kk + 1][] = '?';
                            }
                            unset($patientform[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]);
                        } elseif ($patientformcomplete == 1) {
                            if(isset($FormRelationDatas_handle[$vd['form_id']]) && !isset($PatientformInfo_handle[$vv['id'].'-'.$v['id'].'-'.$vd['form_id']])){
                                $data[$kk + 1][] = '--';
                                if(in_array(3,$complete_type)) $data[$kk + 1][$indexK] += 1;
                            }else{
                                if ($patientformcontent[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_yc'] == '-1' && $form[$vd['form_id']]['group_id'] == 7) {
                                    $data[$kk + 1][] = '?';
                                    unset($patientformcontent[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]);
                                } elseif ($form[$vd['form_id']]['group_id'] == 7 && $patientformcontent[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]['is_yc'] == 0) {
                                    $data[$kk + 1][] = 'X';
                                    if(in_array(2,$complete_type)) $data[$kk + 1][$indexK] += 1;
                                } else {
                                    if(in_array(1,$complete_type)) $data[$kk + 1][$indexK] += 1;
                                    $data[$kk + 1][] = '√';
                                }
                            }
                            unset($patientform[$vv['id'] . '-' . $v['id'] . '-' . $vd['form_id']]);
                        } elseif ($patientformcomplete == 9) {

                            if(isset($FormRelationDatas_handle[$vd['form_id']])){
                                if(in_array(3,$complete_type)) $data[$kk + 1][$indexK] += 1;
                                $data[$kk + 1][] = '--';
                            }else{
                                $data[$kk + 1][] = '?';
                            }
                        }
                    }
                }
            }
            $sheetName = $randomDatas[$v['random_id']]['random_name'] . '-' . $v['check_name'];
            $name = str_replace("/", '-', $sheetName);

            $fileObject->addSheet($name)->data($data);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }
        $filePath = $fileObject->output();
    }

    /**
     * Notes : 受试者详细报告导出(纵表)
     * Author:lwl
     * Date:2024/2/26
     */
    public function patientformreport_d($data)
    {
        $item_id = $data['item_id'] ?: '0';
        $itemsig_id = $data['itemsig_ids'] ?: '';
        $patient_status = $data['patient_status'] ?: '10';
        $patient_ids = $data['patient_ids'];

        if (empty($item_id)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');

        //配置导出
        $path = APP_PATH . '/data/exportFile';

        if (file_exists($path) == false) mkdir($path, 0777, true);

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $xlsxObject = new \Vtiful\Kernel\Excel($config);

        $patientColumns = ['id','patient_name','itemsig_id','patient_number','random_id'];
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_ids, $patient_status,$patientColumns);
        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo(empty($itemsig_id) ? 0 : $itemsig_id, $item_id, 0);
        $signDatas = [];
        foreach ($itemsignatoryDatas as $k => $v) {
            $signDatas[$v['value']] = $v['number'];
        }
        unset($patientColumns,$itemsignatoryDatas);

        //查询项目检查点
        $checktimeWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checktimeWhere['columns'] = ['id', 'check_name', 'stage_id', 'random_id'];
        $checktimeWhere['order'] = 'check_order';
        $checktimeDatas = $this->LocalService()->itemChecktime->fetchAll($checktimeWhere);

        //查询表单
        $formWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $formWhere['columns'] = ['id', 'name', 'group_id','gco_pool','info_collect_type'];
        $formWhere['order'] = 'order';
        $formDatas = $this->LocalService()->itemForm->fetchAll($formWhere);

        $form = $poolForm = $pool = $ocrForm = [];
        foreach ($formDatas as $k => $v) {
            if($v['group_id'] == 7) $ocrForm[] = $v['id'];
            $form[$v['id']] = $v;
            if($v['gco_pool'] != '') {
                $poolForm[] = $v['id'];
                $pool[$v['gco_pool']][] = $v['id'];
            }
        }
        $patientformcontentImg = [];
        if(!empty($poolForm)){
            $contentImg = $this->LocalService()->patientFormContentImg->fetchAll([
                'where'=> [
                    'is_del' => 0,
                    'item_id' => $item_id,
                    'form_id' => $poolForm,
                ],
                'columns'=>['id','checktime_id','form_id','patient_id'],
                'group'=>['patient_id','checktime_id','form_id']
            ]);

            foreach($contentImg as $key=>$value){
                $patientformcontentImg[$value['patient_id']][$value['checktime_id']][$value['form_id']] = $value['id'];
            }
            unset($contentImg);
        }
        //查询当前检查点以及表单
        $checkcontentWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checkcontentWhere['columns'] = ['id', 'form_id', 'check_id'];
        $checkcontentWhere['order'] = 'order';
        $checkcontent = $this->LocalService()->itemCheckcontent->fetchAll($checkcontentWhere);
        $checkcontentDatas = [];
        foreach ($checkcontent as $k => $v) {
            $checkcontentDatas[$v['check_id']][] = $v;
        }

        //-------------------------------------------------------------------------------------------------

        $associated_ishide = [];
        foreach($checkcontent as $k=>$v){
            if($v['associated_ishide'] == 1){
                $associated_ishide[] = $v['form_id'];
            }
        }

        //查询当前表单是不是为二级 如果是 查询一级表单是否做过 未做过不显示
        $FormRelationwhere['where'] = [
            'is_del' => 0,
            'relation_form_id' => array_column($checkcontent,'form_id')
        ];
        if(!empty($associated_ishide)){
            $FormRelationwhere['where'][] = new NotIn('relation_form_id', $associated_ishide);
        }

        $FormRelationwhere['columns'] = ['form_id','relation_form_id'];
        $FormRelationDatas=$this->LocalService()->itemFormRelation->fetchAll($FormRelationwhere);

        $FormRelationDatas_handle = [];
        foreach($FormRelationDatas as $k=>$v){
            $FormRelationDatas_handle[$v['relation_form_id']] = $v;
        }
        unset($FormRelationDatas);

        $PatientformInfo = $this->LocalService()->itemPatientChecktimeForm->fetchAll([
            'where' => [
                'item_id' => $item_id,
                'is_del' => 0,
            ]]
        );
        $PatientformInfo_handle = [];
        foreach($PatientformInfo as $isshowK=>$isshowV){
            $PatientformInfo_handle[$isshowV['patient_id'].'-'.$isshowV['checktime_id'].'-'.$isshowV['form_id']] = $isshowV;
        }
        //-------------------------------------------------------------------------------------------------
        //查询受试者表单、化验单是否完成 patienrformcontent
        $patientformcontent = [];
        if(!empty($ocrForm)){
            $patientformWhere['where'] = [
                'is_del' => 0,
                'item_id' => $item_id,
                'form_id' => $ocrForm,
                new Operator('is_yc', Operator::OP_NE, 1)
            ];
            if(!empty($itemsig_id)) $patientformWhere['where']['itemsig_id'] = explode(',', $itemsig_id);
            $patientformWhere['columns'] = ['id', 'patient_id', 'checktime_id', 'form_id', 'is_yc'];
            $patientformcontentDatas = $this->LocalService()->patientFormContent->fetchAll($patientformWhere);
            foreach ($patientformcontentDatas as $k => $v) {
                $patientformcontent[$v['patient_id'] . '-' . $v['checktime_id'] . '-' . $v['form_id']] = $v['is_yc'];
            }
            unset($patientformcontentDatas);
        }

        //查询项目详情
        $iteminfoWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $iteminfoWhere['columns'] = ['id', 'name'];
        $iteminfo = $this->LocalService()->itemInfo->fetchOne($iteminfoWhere);
        unset($iteminfoWhere);

        //随机方案
        $randomWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $randomWhere['columns'] = ['id', 'random_name', 'type'];
        $randomData = $this->LocalService()->itemRandom->fetchAll($randomWhere);
        unset($randomWhere);
        $randomDatas = [];
        foreach ($randomData as $k => $v) {
            $randomDatas[$v['id']] = $v;
        }
        unset($randomData);

        $fileName = $iteminfo['name'] . "受试者进度详细报告(纵表)" . '-' . $data['create_time'] . '.xlsx';

        $fileObject = $xlsxObject->fileName($fileName, '符号定义');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        //ECRF表单
        $symbol_define = [
            ['√','已完成'],
            ['X','不检查'],
            ['?','表单未填写、未填写完或者已开具未传图，颜色为橙色或红色'],
            ['--','不需要填写的表单 如：未触发关联的表单'],
            ['(注：住院医嘱/出院医嘱，有传图 √      未传图 ?)',''],
        ];
        $fileObject->header(['符号', '定义'])->data($symbol_define);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);


        $data = [];
        $kk = 1;
        $arr = ['中心编号'];
        if(!empty($attrnumber)){
            $arr[] = '受试者筛选号';
        }
        $arr1 = ['访视','表单','完成情况'];
        $data[] = array_merge($arr,$arr1);

        $patientform = [];
        //中心
        foreach ($signDatas as $signk => $signv) {
            unset($patientform);
            //受试者填写表单情况

            if(isset($patientDatas[$signk]))$patientform = $this->getPatientFormDatas($item_id,$signk);

            //受试者
            foreach ($patientDatas[$signk] as $key => $vv) {

                //检查点
                foreach ($checktimeDatas as $k => $vc) {


                    if ($vv['random_id'] == '' || $vv['random_id'] == NULL) $vv['random_id'] = 0;
                    //随机分组
                    if ($randomDatas[$vc['random_id']]['type'] == 2) {
                        if ($vv['random_id'] != $vc['random_id']) continue;
                    }

                    if ($vc['random_id'] != $vc['random_id']) continue;
                    //表单
                    foreach ($checkcontentDatas[$vc['id']] as $kd => $vd) {
//                        if($vd['form_id'] <> 1152) continue;

                        if (!isset($form[$vd['form_id']])) {
                            unset($checkcontentDatas[$vc['id']][$kd]);
                            continue;
                        }
                        $patientNumber = '';
                        if(!empty($attrname) && !empty($vv['patient_name'])){
                            $patientNumber .= $vv['patient_name'];
                        }
                        if(!empty($attrnumber) && !empty($vv['patient_number'])){
                            $patientNumber .= '【'.$vv['patient_number'].'】';
                        }

                        $data[$kk][] = $signv;
                        $data[$kk][] = $patientNumber;;
                        $data[$kk][] = $vc['check_name'];
                        $data[$kk][] = $form[$vd['form_id']]['name'];

                        if(in_array($form[$vd['form_id']]['info_collect_type'],['2','3']) && isset($form[$vd['form_id']]['gco_pool']) && isset($pool[$form[$vd['form_id']]['gco_pool']])){
                            //获取到一组的表单ID
                            $flag = false;
                            foreach($pool[$form[$vd['form_id']]['gco_pool']] as $poolK => $poolV){
                                if(isset($patientformcontentImg[$vv['id']][$vc['id']][$poolV])){
                                    $data[$kk][] = '√';
                                    $flag = true;
                                    unset($patientformcontentImg[$vv['id']][$vc['id']][$poolV]);
                                    break;
                                }
                            }
                            if($flag == true) {
                                ++$kk;
                                continue;
                            }

                        }

                        $patientformcomplete = isset($patientform[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']]) ? $patientform[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']] : '9';

                        if($patientformcomplete == 0){
                            if(isset($FormRelationDatas_handle[$vd['form_id']]) && !isset($PatientformInfo_handle[$vv['id'].'-'.$vc['id'].'-'.$vd['form_id']])){
                                $data[$kk][] = '--';
                            }else{
                                $data[$kk][] = '?';
                            }
                            unset($patientform[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']]);
                        }elseif ($patientformcomplete == 1) {
                            if(isset($FormRelationDatas_handle[$vd['form_id']]) && !isset($PatientformInfo_handle[$vv['id'].'-'.$vc['id'].'-'.$vd['form_id']])){
                                $data[$kk][] = '--';
                            }else{
                                if ($patientformcontent[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']] == '-1' && $form[$vd['form_id']]['group_id'] == 7) {
                                    $data[$kk][] = '?';
                                    unset($patientformcontent[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']]);
                                } elseif ($form[$vd['form_id']]['group_id'] == 7 && $patientformcontent[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']] == 0) {
                                    $data[$kk][] = 'X';
                                    unset($patientformcontent[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']]);
                                } else {
                                    $data[$kk][] = '√';
                                }
                            }
                            unset($patientform[$vv['id'] . '-' . $vc['id'] . '-' . $vd['form_id']]);
                        } elseif ($patientformcomplete == 9 || $patientformcomplete == '-1') {
                            if(isset($FormRelationDatas_handle[$vd['form_id']])){
                                $data[$kk][] = '--';
                            }else{
                                $data[$kk][] = '?';
                            }
                        }
                        ++$kk;
                    }
                }
            }
        }

        $sheetName = '受试者进度详情报告';
        $name = str_replace("/", '-', $sheetName);

        $fileObject->addSheet($name)->data($data);

        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        $filePath = $fileObject->output();
    }

    public function getPatientFormDatas($item_id,$itemsig_id){
        $patientformWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'itemsig_id' => $itemsig_id
        ];
        $patientformWhere['columns'] = ['id', 'patient_id', 'checktime_id', 'form_id', 'is_complete'];
        $patientformDatas = $this->LocalService()->patientForm->fetchAll($patientformWhere);
        $patientform = [];
        foreach ($patientformDatas as $v) {
            $patientform[$v['patient_id'] . '-' . $v['checktime_id'] . '-' . $v['form_id']] = $v['is_complete'];
        }

        return $patientform;
    }

    /**
     * Notes : 受试者失访报告导出
     * Author:tyy
     * Date:2022/9/22 11:30
     */
    public function exportbooked($data)
    {
        $item_id = $data['item_id'] ?: 0;
        $itemsig_id = $data['itemsig_ids'] ?: '';
        $patient_id = $data['patient_ids'] ?: '';       //受试者ID
        if (empty($item_id)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');

        //获取中心信息
        $newItemSignInfoData = $this->LocalService()->itemSignatory->getItemSignatoryData(['flag' => 0, 'item_id' => $item_id, 'itemsig_id' => $itemsig_id]);
        $itemsig_id_arr = $itemsig_arr = [];
        if (!empty($newItemSignInfoData)) {
            foreach ($newItemSignInfoData as $newItemSignInfo) {
                $newItemSignId = $newItemSignInfo['id'];
                $itemsig_id_arr[] = $newItemSignId;
                $itemsig_arr[$newItemSignId] = !empty($newItemSignInfo['number']) ? $newItemSignInfo['number'] : $newItemSignInfo['info_name'];
            }
        }
        unset($newItemSignInfoData);

        //获取受试者检查点失访、筛败、完成、终止、脱落信息
        $patientchecktime_where = $patient_where = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if (!empty($itemsig_id_arr)) {
            $patientchecktime_where['itemsig_id'] = $itemsig_id_arr;
            $patient_where['itemsig_id'] = $itemsig_id_arr;
        } else {
            $patientchecktime_where = $patient_where = [
                new Operator('id', Operator::OP_LT, 0)
            ];
        }
        unset($itemsig_id_arr);
        if (!empty($patient_id)) {
            $patientchecktime_where['patient_id'] = StringHelper::toArray($patient_id);
            $patient_where['patient_id'] = StringHelper::toArray($patient_id);
        }
        $patientchecktimes = $this->LocalService()->itemPatientchecktime->getPatientChecktimeByKey($patientchecktime_where, ['patientchecktime_id' => 'id', 'patient_id', 'researchstage_id', 'checktime_id', 'leave_type', 'is_no_booked', 'checktime_name', 'check_order', 'make_time', 'random_id'], ['random_id', 'check_order'], ['patient_id' => 1]);
        unset($patientchecktime_where);

        //获取受试者计划内检查点 及 计划内后的计划外检查点
        $patientchecktime_arr = [];
        if (!empty($patientchecktimes) && !empty($patientchecktimes['patient_id'])) {
            foreach ($patientchecktimes['patient_id'] as $patientchecktimKey => $patientchecktime_datas) {
                $patient_prechecktime = 0;
                foreach ($patientchecktime_datas as $patientchecktime_data) {
                    $patientchecktime_timeid = $patientchecktime_data['checktime_id'];
                    if (!empty($patientchecktime_timeid)) {
                        $patientchecktime_key = $patientchecktimKey . '_' . $patientchecktime_timeid;
                        $patientchecktime_arr['plan'][$patientchecktime_key] = $patientchecktime_data;
                        $patient_prechecktime = $patientchecktime_timeid;
                        unset($patientchecktime_key);
                    } else {
                        $patientchecktime_key = $patientchecktimKey . '_' . $patient_prechecktime;
                        $patientchecktime_arr['out'][$patientchecktime_key][] = $patientchecktime_data;
                        unset($patientchecktime_key);
                    }
                    $patientchecktime_arr['id'][] = $patientchecktime_data['patientchecktime_id'];
                    unset($patientchecktime_timeid);
                }
                unset($patientchecktimes['patient_id'][$patientchecktimKey]);
                unset($patient_prechecktime);
            }
            unset($patientchecktimes['patient_id']);
        }
        unset($patientchecktimes);

        //获取预约备注
        $patientchecktime_booked_arr = [];
        if (isset($patientchecktime_arr['id'])) {
            $booked_datas = $this->LocalService()->itemPatientbooked->fetchAll([
                'where' => [
                    'is_del' => 0,
                    'patientchecktime_id' => $patientchecktime_arr['id'],
                ],
                'columns' => ['patientchecktime_id', 'remarks']
            ]);
            if (!empty($booked_datas)) {
                foreach ($booked_datas as $booked_data_key=>$booked_data) {
                    $booked_data_patientchecktime = $booked_data['patientchecktime_id'];
                    $patientchecktime_booked_arr[$booked_data_patientchecktime] = $booked_data['remarks'];
                    unset($booked_datas[$booked_data_key]);
                }
            }
            unset($booked_datas);
            unset($patientchecktime_arr['id']);
        }

        //获取受试者信息并重组受试者检查点信息
        $itempatient_arr = $this->LocalService()->patient->getPatientByKey($patient_where, ['id', 'itemsig_id', 'patient_number', 'patient_name'], ['patient_order'], 'itemsig_id');
        unset($patient_where);
        if (!empty($itempatient_arr)) {
            //获取项目下设置的检查点信息
            $itemchecktime_arr = $this->LocalService()->itemChecktime->getChecktimeByKey([
                'is_del' => 0,
                'item_id' => $item_id,

            ], ['checktime_id' => 'id', 'random_id', 'checktime_name' => 'check_name', 'researchstage_id' => 'stage_id', 'check_order'], ['random_id', 'check_order'], ['random_id' => 1]);
            $random_arr = $this->LocalService()->itemRandom->fetchCol('random_name', [
                'is_del' => 0,
                'item_id' => $item_id,
            ], ['random_order']);//获取方案分组信息
            foreach ($itempatient_arr as $itemsigKey => $patient_arr) {
                foreach ($patient_arr as $patientKey => $patient) {
                    $patient_id = $patient['id'];
                    $patient_outchecktime_key = $patient_id . '_0';
                    if (isset($patientchecktime_arr['out']) && isset($patientchecktime_arr['out'][$patient_outchecktime_key]) && !empty($patientchecktime_arr['out'][$patient_outchecktime_key])) {
                        foreach ($patientchecktime_arr['out'][$patient_outchecktime_key] as $patient_outchecktime) {
                            $patient_outchecktime_data = $patient_outchecktime;
                            $patient_outchecktime_random = $patient_outchecktime['random_id'];
                            $patient_outchecktime_id = $patient_outchecktime['patientchecktime_id'];
                            $patient_outchecktime_data['booked_remark'] = isset($patientchecktime_booked_arr[$patient_outchecktime_id]) && !empty($patientchecktime_booked_arr[$patient_outchecktime_id]) ? $patientchecktime_booked_arr[$patient_outchecktime_id] : '';
                            if (isset($random_arr[$patient_outchecktime_random])) {
                                $patient_outchecktime_data['checktime_name'] .= '【' . $random_arr[$patient_outchecktime_random] . '】';
                            }
                            $itempatient_arr[$itemsigKey][$patientKey]['checktime'][] = $patient_outchecktime_data;
                        }
                    }
                    if (!empty($random_arr) && !empty($itemchecktime_arr) && isset($itemchecktime_arr['random_id'])) {
                        foreach ($random_arr as $randomid => $random_name) {
                            if (isset($itemchecktime_arr['random_id'][$randomid]) && !empty($itemchecktime_arr['random_id'][$randomid])) {
                                foreach ($itemchecktime_arr['random_id'][$randomid] as $itemchecktime) {
                                    $item_patient_checktime = $itemchecktime;
                                    $item_patient_checktime['booked_remark'] = '';
                                    $item_patient_checktime_id = $itemchecktime['checktime_id'];
                                    $patient_checktime_key = $patient_id . '_' . $item_patient_checktime_id;
                                    //计划内检查点信息
                                    if (isset($patientchecktime_arr['plan']) && isset($patientchecktime_arr['plan'][$patient_checktime_key]) && !empty($patientchecktime_arr['plan'][$patient_checktime_key])) {
                                        unset($patientchecktime_arr['plan'][$patient_checktime_key]['checktime_name']);
                                        unset($patientchecktime_arr['plan'][$patient_checktime_key]['check_order']);
                                        unset($patientchecktime_arr['plan'][$patient_checktime_key]['checktime_id']);
                                        unset($patientchecktime_arr['plan'][$patient_checktime_key]['researchstage_id']);
                                        unset($patientchecktime_arr['plan'][$patient_checktime_key]['random_id']);
                                        $item_patient_checktime['checktime_name'] .= '【' . $random_name . '】';
                                        $item_patientchecktime_id = $patientchecktime_arr['plan'][$patient_checktime_key]['patientchecktime_id'];
                                        $item_patient_checktime['booked_remark'] = isset($patientchecktime_booked_arr[$item_patientchecktime_id]) && !empty($patientchecktime_booked_arr[$item_patientchecktime_id]) ? $patientchecktime_booked_arr[$item_patientchecktime_id] : '';
                                        $item_patient_checktime = array_merge($item_patient_checktime, $patientchecktime_arr['plan'][$patient_checktime_key]);
                                        unset($item_patientchecktime_id);
                                    }
                                    $itempatient_arr[$itemsigKey][$patientKey]['checktime'][] = $item_patient_checktime;
                                    unset($item_patient_checktime_id);
                                    unset($item_patient_checktime);

                                    //计划内后的计划外检查点信息
                                    if (isset($patientchecktime_arr['out']) && isset($patientchecktime_arr['out'][$patient_checktime_key]) && !empty($patientchecktime_arr['out'][$patient_checktime_key])) {
                                        foreach ($patientchecktime_arr['out'][$patient_checktime_key] as $patient_checktime_out) {
                                            $item_patient_outchecktime = $patient_checktime_out;
                                            $item_patient_outchecktime['checktime_name'] .= '【' . $random_name . '】';
                                            $patient_checktime_out_id = $patient_checktime_out['patientchecktime_id'];
                                            $item_patient_outchecktime['booked_remark'] = isset($patientchecktime_booked_arr[$patient_checktime_out_id]) && !empty($patientchecktime_booked_arr[$patient_checktime_out_id]) ? $patientchecktime_booked_arr[$patient_checktime_out_id] : '';
                                            $itempatient_arr[$itemsigKey][$patientKey]['checktime'][] = $item_patient_outchecktime;
                                            unset($patient_checktime_out_id);
                                            unset($item_patient_outchecktime);
                                        }
                                    }
                                    unset($patient_checktime_key);
                                }
                            }
                        }
                    }
                }
            }
            unset($itemchecktime_arr);
            unset($random_arr);
        }
        unset($patientchecktime_arr);
        unset($patientchecktime_booked_arr);

        //重组导出数据
        $datas = [];
        if (!empty($itempatient_arr)) {
            $stage_arr = $this->LocalService()->itemResearchstage->fetchCol('stage_name', [
                'is_del' => 0,
                'item_id' => $item_id,
            ], ['stage_order']);
            $leave_type_arr = [1 => '脱落', 2 => '筛败', 3 => '完成', 4 => '中止'];
            foreach ($itemsig_arr as $itemsigid => $itemsig_name) {
                if (isset($itempatient_arr[$itemsigid]) && !empty($itempatient_arr[$itemsigid])) {
                    foreach ($itempatient_arr[$itemsigid] as $itempatient_key=>$itempatient) {
                        $itempatient_checktimes = isset($itempatient['checktime']) && !empty($itempatient['checktime']) ? $itempatient['checktime'] : [];
                        if (!empty($itempatient_checktimes)) {
                            $patient_number_name = !empty($itempatient['patient_number']) ? $itempatient['patient_number'] : $itempatient['patient_name'];
                            foreach ($itempatient_checktimes as $itempatient_checktime_key=>$itempatient_checktime) {
                                //阶段检查点方案分组信息
                                $stage_time_name = $itempatient_checktime['checktime_name'];
                                $patientchecktime_stageid = $itempatient_checktime['researchstage_id'];
                                if (isset($stage_arr[$patientchecktime_stageid])) {
                                    $stage_time_name = $stage_arr[$patientchecktime_stageid] . '-' . $stage_time_name;
                                }

                                //失访、状态信息
                                $booked_leave = '-';
                                if (isset($itempatient_checktime['patientchecktime_id']) && !empty($itempatient_checktime['patientchecktime_id'])) {
                                    $booked_leave = '';
                                    if ($itempatient_checktime['is_no_booked'] == 1) {
                                        $booked_leave = '是';
                                    } else {
                                        if ($itempatient_checktime['is_no_booked'] != 1 && !empty($itempatient_checktime['make_time'])) {
                                            $booked_leave = '否';
                                        }
                                    }
                                    if (!empty($itempatient_checktime['leave_type']) && $itempatient_checktime['leave_type'] != 9) {
                                        $patientchecktime_leave_type = $itempatient_checktime['leave_type'];
                                        $booked_leave = !empty($booked_leave) ? $booked_leave . '/' . $leave_type_arr[$patientchecktime_leave_type] : $leave_type_arr[$patientchecktime_leave_type];
                                        unset($patientchecktime_leave_type);
                                    }
                                }

                                $excel_data = [];
                                $excel_data[] = $itemsig_name;
                                $excel_data[] = $patient_number_name;
                                $excel_data[] = $stage_time_name;
                                $excel_data[] = $booked_leave;
                                $excel_data[] = empty($itempatient_checktime['booked_remark']) ? '' : $itempatient_checktime['booked_remark'];
                                $datas[] = $excel_data;

                                unset($stage_time_name);
                                unset($patientchecktime_stageid);
                                unset($booked_leave);
                                unset($itempatient_checktimes[$itempatient_checktime_key]);
                            }
                            unset($patient_number_name);
                        }
                        unset($itempatient_checktimes);
                        unset($itempatient_arr[$itemsigid][$itempatient_key]);
                    }
                    unset($itempatient_arr[$itemsigid]);
                }
                unset($itemsig_arr[$itemsigid]);
            }
            unset($stage_arr);
            unset($leave_type_arr);
        }
        unset($itemsig_arr);
        unset($itempatient_arr);

        //配置导出
        $path = APP_PATH . '/data/exportFile';
//        $path = APP_PATH.'/public/img';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $item_name = $this->LocalService()->itemInfo->getOneFieldVal('name', [
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称
        $fileName = $item_name . "受试者失访报告" . '-' . $data['create_time'] . '.xlsx';
        $fileObject = $xlsxObject->fileName($fileName, '失访报告');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header(['中心编号', '筛选号/编号', '检查点', '失访登记', '备注说明'])->data($datas);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        //输出数据
        $filePath = $fileObject->output();

        unset($item_name);
        unset($datas);
    }

    /**
     * Notes : 项目名称
     * @param $item_id
     * @return mixed|string|null
     * Author:唐伯虎不虎
     * Date:2022/10/12 10:45
     */
    public function getitemName($item_id)
    {
        if (!$this->itemInfo) {
            $itemWhere['where'] = [
                'is_del' => 0,
                'id' => $item_id
            ];
            $itemWhere['columns'] = ['id', 'name', 'number'];
            $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
            $this->itemInfo = $itemInfo;
        }
        return $this->itemInfo;
    }

    /**
     * Notes : 导出随机号明细 默认导出项目下所有研究分层
     * Author:唐伯虎不虎
     * Date:2022/10/11 9:27
     */
    public function randomData($data)
    {
        //获取项目ID 分层信息
        $random_ids = $data['random_ids'];

        $item_id = $data['item_id'];

        $create_time = $data['create_time'];

        //查询项目研究分层
        $randgroupWhere['where'] = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        if ($random_ids != 0) $randgroupWhere['where']['id'] = StringHelper::toArray($random_ids);
        $randgroupWhere['columns'] = ['id', 'group_name'];
        $randgroupWhere['order'] = 'randgroup_order';
        $randgroupDatas = $this->LocalService()->itemRandgroup->fetchAll($randgroupWhere);

        //批次数据
        $batch = [];

        //查询研究分层下的批次
        foreach ($randgroupDatas as $key => $value) {
            $randnumberWhere['where'] = [
                'item_id' => $item_id,
                'is_del' => 0,
                'randgroup_id' => $value['id']
            ];
            $randnumberWhere['columns'] = ['id', 'randgroup_id', 'item_sign_id', 'fontend_name', 'frist_name', 'randnumber_number'];
            $randnumberWhere['order'] = 'randnumber_order';
            $randnumberDatas = $this->LocalService()->itemRandnumber->fetchAll($randnumberWhere);
            if (!empty($randnumberDatas)) {
                foreach ($randnumberDatas as $k => $v) {
                    $v['group_name'] = $value['group_name'];
                    $batch[] = $v;
                }
            }
        }

        if (empty($batch)) return false;

        //查询项目方案分组
        $randomDatas = $this->LocalService()->itemRandom->fetchCol('random_name', [
            'item_id' => $item_id,
            'is_del' => 0,
        ]);

        //查询随机号明细
        $randomdetailsWhere['where'] = [
            'item_id' => $item_id,
            'is_annul' => 0,
        ];
        if ($random_ids != 0) $randomdetailsWhere['where']['randgroup_id'] = StringHelper::toArray($random_ids);
        $randomdetailsWhere['columns'] = ['id', 'randnumber_id', 'programme_id', 'item_sign_id', 'randomdetails_name', 'area_code', 'medication_id', 'is_del', 'is_use'];
        $randomdetailsWhere['order'] = 'randomdetails_order';
        $randomdetailsDatas = $this->LocalService()->itemRandomdetails->fetchAll($randomdetailsWhere);

        $randomdetails = [];
        //按照批次放入数组
        foreach ($randomdetailsDatas as $k => $v) {
            $randomdetails[$v['randnumber_id']][] = $v;
        }

        //获取中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo(0, $item_id, 0);
        $signatory = [];
        foreach ($itemsignatoryDatas as $k => $v) {
            $signatory[$v['value']] = $v['label'];
        }

        //药物分组
        $medicationWhere['where'] = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        $medicationWhere['columns'] = ['id', 'medication_name'];
        //药物分组
        $medicationDatas = $this->LocalService()->itemMedication->fetchCol('medication_name', [
            'item_id' => $item_id,
            'is_del' => 0,
        ]);
        //药物分组信息
        $medicationMessageDatas = $this->LocalService()->itemMedication->fetchCol('medication_message', [
            'item_id' => $item_id,
            'is_del' => 0,
        ]);

        $randGroup = [];

        $catalogue = ['序号', '研究分层-批次'];

        $groupFontend = [];

        //查询大项目
        $item_fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
            'id' => $item_id,
            'is_del' => 0,
        ]);//获取项目名称
        $blind_method = $this->LocalService()->itemInfo->getOneFieldVal('blind_method', [
            'id' => $item_fid,
            'is_del' => 0,
        ]);//获取项目名称

        //处理分组以及批次
        foreach ($batch as $k => $v) {

            if ($blind_method == 0) {
                //展示
                $data = Exportenum::RandNumber;
            } else {
                //不展示
                $data = Exportenum::RandNumber_01;
            }

            if (empty($randomdetails[$v['id']])) continue;

            //[['分层名称','方案分组','区组号','研究中心','随机号码','药物分组名称','药物信息','是否被调用','是否作废']];
            foreach ($randomdetails[$v['id']] as $key => $value) {
                $dataKey = $key + 1;
                //分层名称
                $data[$dataKey][] = $v['group_name'];

                if ($blind_method == 0) {
                    //方案分组
                    $data[$dataKey][] = $randomDatas[$value['programme_id']];
                }

                //区组号
                $data[$dataKey][] = $value['area_code'] ?: '';

                //研究中心
                if ($value['item_sign_id'] != 0) {
                    $data[$dataKey][] = $signatory[$value['item_sign_id']];
                } else {
                    $data[$dataKey][] = '未分配研究中心';
                }

                //随机号码
                $data[$dataKey][] = $value['randomdetails_name'];

                if ($blind_method == 0) {
                    //药物分组名称--药物信息
                    if ($value['medication_id'] != 0) {
                        $data[$dataKey][] = $medicationDatas[$value['medication_id']];
                        $data[$dataKey][] = $medicationMessageDatas[$value['medication_id']];
                    } else {
                        $data[$dataKey][] = '';
                        $data[$dataKey][] = '';
                    }
                }

                //是否被调用
                $data[$dataKey][] = $value['is_use'] ? '是' : '否';

                //是否作废
                $data[$dataKey][] = $value['is_del'] ? '是' : '否';

            }

            //sheet名称
            $sheetName = $v['group_name'] . '-' . ($k + 1);

            //研究分层-批次
            $groupFontendKey = $k + 1;
            $groupFontend[$groupFontendKey][] = $groupFontendKey;
            $groupFontend[$groupFontendKey][] = $sheetName;
            //写入大数组
            $groupfontendName = str_replace("/", '-', $sheetName);
            $groupfontendName = str_replace("[", '【', $groupfontendName);
            $groupfontendName = str_replace("]", '】', $groupfontendName);
            $groupfontendName = str_replace("？", '', $groupfontendName);
            $randGroup[$groupfontendName] = $data;
        }


        $item_name = $this->getitemName($item_id)['name'];

        $item_name .= '随机号明细';
        $this->dataExport($item_name, $create_time, $catalogue, $groupFontend, $randGroup);

    }

    /**
     * Notes : 随机号明细处理
     * @param $itemInfo
     * @param $create_time
     * @param $catalogue
     * @param $firstData
     * @param $dataArr
     * Author:唐伯虎不虎
     * Date:2024/5/13 14:47
     */
    public function dataExport($itemInfo, $create_time, $catalogue, $firstData, $dataArr)
    {
        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo . '-' . $create_time . '.xlsx';

        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header($catalogue)->data($firstData);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //循环指标数据生成sheet
        foreach ($dataArr as $k => $v) {
            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }
            $fileObject->addSheet($sheetName)->data($dataArr[$k]);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }

        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes : 日志导出
     * @param $data
     * Author:唐伯虎不虎
     * Date:2024/5/13 14:48
     */
    public function logData($data)
    {
        $item_id = $data['item_id'];
        $log_type = $data['log_type'];
        $log_start_time = $data['log_start_time'];
        $operation_source = $data['operation_source'];
        $operation_type = $data['operation_type'];
        $operationuser_ids = $data['operationuser_ids'];
        $fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
            'item_id' => $item_id,
            'is_del' => 0,
        ]);//获取项目名称

        $log_start_time = !empty($log_start_time) ? $log_start_time : strtotime(date('Y-m-01', time()));

        $syslogWhere = [
            'item_id' => [$item_id, $fid],
        ];

        if (!empty($log_start_time)) {
            $syslogWhere[] = new Operator('create_time', Operator::OP_GTE, $log_start_time);
        }
        if (!empty($operation_source)) {
            $syslogWhere['log_type'] = $operation_source;
        }
        if (!empty($operation_type)) {
            $syslogWhere['oper_type'] = $operation_type;
        }
        if (!empty($operation_type)) {
            $syslogWhere['user_id'] = explode(',', $operationuser_ids);
        }
        $itemWhere['where'] = [
            'id' => $item_id,
            'is_del' => 0,
        ];
        $itemWhere['columns'] = ['name'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        $excelHeader = ['操作人', '操作时间', '操作类型', 'IP地址', '操作来源', '项目', '操作描述'];

        $logtype['where'] = [
            'is_del' => 0,
        ];
        if (!empty($log_type)) {
            $logtype['where']['id'] = explode(',', $log_type);
        }
        $result = $this->LocalService()->itemLogtype->fetchAll($logtype);
        $event = [];
        $eventFormData = [];
        foreach ($result as $k => $v) {
            $event[] = $v['logtype_action'];
            $eventFormData[$v['logtype_action']] = $v['logtype_name'];
        }

        if (!empty($log_type)) {
            $syslogWhere['event_from'] = $event;
        }

        $count = $this->LocalService()->adminLog->getCount($syslogWhere);

        $count = $count / 100;


        // 创建 Excel 对象
        $excelObj = new Excel([
            'path' => APP_PATH . '/data/exportFile'
        ]);

        $fileName = "日志导出" . '-' . $data['create_time'];

        $excelFileObj = $excelObj->fileName($fileName . '.xlsx', $eventFormData[key($eventFormData)])->header($excelHeader);
        $excelFileHandle = $excelFileObj->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        // 向文件中追加一个工作表
        if (!empty($eventFormData)) {
            $index = 0;
            foreach ($eventFormData as $event_code => $event_form_name) {

                if ($index) {
                    $formname = str_replace("/", '-', $event_form_name);
                    $formname = str_replace("[", '【', $formname);
                    $formname = str_replace("]", '】', $formname);
                    $formname = str_replace("？", '', $formname);

                    $excelFileObj->addSheet($formname)->header($excelHeader);
                }
                $excelFileObj->setRow('A1:F1', 20, $headerBgStyle)->setColumn('A1:E1', 20)->setColumn('F1:F1', 80)->freezePanes(1, 6);

                ++$index;
            }
        }
        if ($count) {
            $oper_type_data = ['新增', '编辑', '删除'];
            $log_type_data = ['0' => '后台', '1' => 'Real', '3' => '小程序']; // 0后台，1real 3小程序
            // 系统后台用户名称信息
            $sysUserNameDatas = $this->LocalService()->adminUser->fetchCol('realname', 'is_del = 0');
            $page = ceil($count / 10000);

            $yeildLogDatas = $this->yieldDbData($page, $syslogWhere);

            foreach ($yeildLogDatas as $logDatas) {
                if (!empty($logDatas)) {
                    $datas = self::yieldFuc($logDatas, $oper_type_data, $log_type_data, $sysUserNameDatas);
                    foreach ($datas as $data) {
                        if ($excelFileObj->existSheet($eventFormData[$data['event_from']])) {

                            $data['change_data'] = str_ireplace('<br>', "", $data['change_data']);

                            $excelFileObj->checkoutSheet($eventFormData[$data['event_from']])->data([[$data['user_realname'], $data['create_time'], $data['oper_type_title'], $data['log_ip'], $data['log_type_title'], $itemInfo['name'], $data['change_data'] . $data['log_remark']]]);
                        } else {
                            $data['event_from'] . '</br>';
                        }
                    }
                }
            }
        }

        $filePath = $excelFileObj->output();
    }

    public function formlogData($data)
    {
        //删除pdf文件夹
        $item_id           = $data['item_id'];
        $log_start_time    = $data['log_start_time']; //开始时间
        $log_end_time      = $data['log_end_time']; //结束时间
        $operation_event   = $data['operation_type'];     //操作动作
        $operationuser_ids = $data['operationuser_ids']; //操作人

        $syslogWhere = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];

        if (!empty($log_start_time)) {
            $syslogWhere[] = new Operator('create_time', Operator::OP_GTE, $log_start_time);
        }

        if (!empty($log_end_time)) {
            $syslogWhere[]  = new Operator('create_time', Operator::OP_LTE, $log_end_time);
        }

        if (!empty($operationuser_ids)) {
            $syslogWhere['create_user_id'] = explode(',', $operationuser_ids);
        }

        if (!empty($operation_event)) {
            $action_arr = ['1'=>'FORM_CONTENT_CREATE','2'=>'FORM_CONTENT_EDIT','3'=>'FORM_CONTENT_FLUSH','4'=>'LOCK_SHARE_FORM_CONTENT','5'=>'UNLOCK_SHARE_FORM_CONTENT','6'=>'CONTENT_EDIT_BY_QUESTION','7'=>'LOCK_SHARE_FORM_CONTENT','8'=>'FORM_CONTENT_TEMP_STORAGE','9'=>'FORM_CHECK_SAVE','10'=>'FORM_CHECK_LOCK','11'=>'FORM_CHECK_UNLOCK','12'=>'FORM_CHECK_REPAIR'];
            $action_event = $action_arr[$operation_event];
            $syslogWhere[] = new Expression("event REGEXP ?", $action_event);
        }

        $itemWhere['where']   = [
            'id' => $item_id,
            'is_del' => 0,
        ];
        $itemWhere['columns'] = ['number','name'];
        $itemInfo             = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        $excelHeader = ['项目编号', '中心编号'];
        $fid = $this->LocalService()->itemInfo->getOneFieldVal('fid',[
            'id' => $item_id
        ]);
        $show_attr_number = $show_attr_name = 0;
        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称
        if (!empty($attrnumber)) {
            $show_attr_number = 1;
            $excelHeader[]    = '筛选号';
        }
        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_del' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称
        if (!empty($attrname)) {
            $show_attr_name = 1;
            $excelHeader[]  = '受试者姓名';
        }

        $new_header  = ['访视名称', '表单序号', '字段名称', '录入值', '更正值', '操作原因', '操作动作', '操作者/角色', '操作时间'];
        $excelHeader = array_merge($excelHeader, $new_header);

        $count = $this->LocalService()->patientFormContentUpdatedLog->getCount($syslogWhere);

        $down_path = APP_PATH . '/data/exportFile';
        // 检查目录是否存在，如果不存在则创建
        if (!file_exists($down_path)) {
            mkdir($down_path, 0777, true); // 创建目录，设置权限为0777
        }

        // 创建 Excel 对象
        $excelObj = new Excel([
            'path' => APP_PATH . '/data/exportFile'
        ]);

        $formNameArr = $this->LocalService()->itemForm->fetchCol('name',[
            'item_id' => $item_id,
            'is_del' => 0,
        ]);
        $eventFormData = $this->LocalService()->itemForm->fetchCol('id',[
            'item_id' => $item_id,
            'is_del' => 0,
        ]);

        $fileName = $itemInfo['name']."表单日志导出" .'-'. $data['create_time'].'.xlsx';
        //echo $fileName;die;
        $excelFileObj = $excelObj->fileName($fileName, $formNameArr[reset($eventFormData)])->header($excelHeader);
        $excelFileHandle = $excelFileObj->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        // 向文件中追加一个工作表
        if (!empty($eventFormData)) {
            $index = 0;

            foreach ($eventFormData as  $eventform) {
                $event_form_name   = !empty($formNameArr[$eventform]) ? $formNameArr[$eventform] : '';
                $formname = str_replace("/", '-', $event_form_name);
                $formname = str_replace("[", '【', $formname);
                $formname = str_replace("]", '】', $formname);
                $formname = str_replace("？", '', $formname);
                $formname = str_replace("（", '【', $formname);
                $formname = str_replace("）", '】', $formname);
                $formname = str_replace(" ", '', $formname);
                if ($index) {
                    $excelFileObj->addSheet($formname)->header($excelHeader);
                }
                $excelFileObj->setRow('A1:L1', 20, $headerBgStyle)->setColumn('A1:E1', 20)->setColumn('F1:L1', 20)->freezePanes(1, 6);
                ++$index;
            }
        }

        if ($count) {
            $page = ceil($count / 10000);
            $yeildLogDatas = $this->yieldformDbData($page, $syslogWhere);
            $res = [];
            $conditionsString = [
                'item_id' => $item_id,
            ];

            //查询项目名称数组
            $itemDatas     = $this->LocalService()->itemInfo->fetchDataByKey([
                'is_del' => 0,
            ], ['id', 'name', 'number', 'fid'], ['id'], ['id' => 0]);
            $itemData      = isset($itemDatas['id']) ? $itemDatas['id'] : [];
            $itemFormArr   = $this->LocalService()->itemForm->fetchCol('group_id', $conditionsString);
            $randGroupArr  = $this->LocalService()->itemRandgroup->fetchCol('group_name', $conditionsString);
            $randomArr = $this->LocalService()->itemRandom->fetchCol('random_name',$conditionsString);
            $randomNameArr = $this->LocalService()->itemRandomdetails->fetchDataInfos($conditionsString);
            //受试者编号数组
            $patientDatas   = $this->LocalService()->patient->fetchDataByKey($conditionsString, ['id', 'patient_name', 'patient_number'], ['id'], ['id' => 0]);
            $patientData    = isset($patientDatas['id']) ? $patientDatas['id'] : [];
            $itemFormArr    = $this->LocalService()->itemForm->fetchCol('group_id', $conditionsString);
            $itemFormType   = $this->LocalService()->itemForm->fetchCol('type', $conditionsString);
            $item_checkName = $this->LocalService()->itemChecktime->fetchCol('check_name', $conditionsString);
            //查询字段名称数组
            list($filedSon_arr, $filedName_arr) = $this->LocalService()->itemFormField->getSonNameArr();

            list($checktime_datas, $nochecktime_datas) = $this->LocalService()->patientFormContent->fetchRelationArr([
                'item_id' => $item_id
            ]);
            //查询人员姓名数组
            $userNameArr = $this->LocalService()->adminUser->fetchCol('realname', [
                'is_del' => 0,
            ]);
            list($sig_user_arr, $user_role_arr, $siguser_role_arr, $itemsig_arr) = $this->LocalService()->realRole->getUserRole(['item_id'=>$fid]);
            //角色数组
            $roleNameArr = $this->LocalService()->realRole->fetchCol('role_name',[
                'is_del' => 0,
                'item_id' => $fid,
            ]);
            $medicaltakeArr  = $this->LocalService()->collectMedicaltake->fetchCol('name',[
                'take_type' => 6
            ]);
            $formNameArr = $this->LocalService()->itemForm->fetchCol('name','id>0');
            foreach ($yeildLogDatas as $logDatas) {

                if (!empty($logDatas)) {

                    $result_data  = [
                        'filedName_arr'    => $filedName_arr,
                        'filedSon_arr'     => $filedSon_arr,
                        'randGroupArr'     => $randGroupArr,
                        'randomNameArr'    => $randomNameArr,
                        'userNameArr'      => $userNameArr,
                        'roleNameArr'      => $roleNameArr,
                        'sig_user_arr'     => $sig_user_arr,
                        'siguser_role_arr' => $siguser_role_arr,
                        'itemsig_arr'      => $itemsig_arr,
                        'itemData'         => $itemData,
                        'medicaltakeArr'   => $medicaltakeArr,
                        'formNameArr'      => $formNameArr,
                        'randomArr'        => $randomArr,
                    ];
                    $event_arr = $this->LocalService()->patientFormContentUpdatedLog->geteventArr();
                    foreach ($logDatas as $logData) {
                            $form_id      = $logData['form_id'];
                            $checktime_id = $logData['checktime_id'];
                            $patient_id   = $logData['patient_id'];
                            $event_form   = isset($formNameArr[$form_id]) && !empty($formNameArr[$form_id]) ? $formNameArr[$form_id] : '';
                            //'项目编号', '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号','字段名称','录入值','更正值','操作原因','操作动作','操作者/角色','操作时间'
                        if ($excelFileObj->existSheet($event_form)) {
                            $insert_data = [$itemInfo['number'], '01'];
                            if ($show_attr_number == 1) {
                                //受试者编号 显示 查询受试者编号 筛选号
                                $insert_data[] = isset($patientData[$patient_id]['patient_number']) && !empty($patientData[$patient_id]['patient_number']) ? $patientData[$patient_id]['patient_number'] : $patientData[$patient_id]['patient_number'];
                            }
                            if ($show_attr_name == 1) {
                                //受试者姓名 显示 查询受试者姓名
                                $insert_data[] = isset($patientData[$patient_id]['patient_name']) && !empty($patientData[$patient_id]['patient_name']) ? $patientData[$patient_id]['patient_name'] : $patientData[$patient_id]['patient_name'];
                            }
                            //访视名称就是检查点名称 表单序号是指 一对多表单 的序号， form表 type = 2 就是一对多表单，然后查出表单内容后排序就有了序号
                            //根据patient_id checktime_id itemsig_id form_id 查yikeen_item_patient_form_content表 从而查出表单序号 当表单的group_id == 4  不查检查点ID
                            //1. 查检查点名称
                            $group_id   = isset($itemFormArr[$form_id]) && !empty($itemFormArr[$form_id]) ? $itemFormArr[$form_id] : 0;
                            $check_name = isset($item_checkName[$checktime_id]) && !empty($item_checkName[$checktime_id]) ? $item_checkName[$checktime_id] : 0;
                            $form_type  = isset($itemFormType[$form_id]) && !empty($itemFormType[$form_id]) ? $itemFormType[$form_id] : 0;
                            $form_order = 1;

                            if ($form_type == 1) {
                                //一对多表单
                                $content_id = $logData['content_id'];
                                $patient_id = $logData['patient_id'];
                                $itemsig_id = $logData['sign_id'];
                                //echo $patient_id.'=='.$itemsig_id.'=='.$form_id;die;
                                $form_content = isset($checktime_datas[$patient_id][$checktime_id][$itemsig_id][$form_id]) && !empty($checktime_datas[$patient_id][$checktime_id][$itemsig_id][$form_id]) ? $checktime_datas[$patient_id][$checktime_id][$itemsig_id][$form_id] : [];
                                if ($group_id == 4) {
                                    //不查检查点ID
                                    $form_content = isset($nochecktime_datas[$patient_id][$itemsig_id][$form_id]) && !empty($nochecktime_datas[$patient_id][$itemsig_id][$form_id]) ? $nochecktime_datas[$patient_id][$itemsig_id][$form_id] : [];
                                }
                                //查询表单序号
                                if (in_array($content_id, $form_content)) {
                                    $form_order = array_search($content_id, $form_content);
                                    $form_order = $form_order + 1;
                                }
                            }

                            $event = isset($event_arr[$logData['event']]) && !empty($event_arr[$logData['event']]) ? $event_arr[$logData['event']] : '其他操作';
                            $result_data['group_id'] = $group_id;
                            $orange_data = $logData['data'];   //录入值
                            //if($event == '添加表单' || $event =='共享图片新增'){
                            if($event == '添加表单'||$event =='共享图片新增' || $event =='共享图片编辑' || $event =='表单激活' || $event =='表单失活'){
                                $result_data['jsonString'] = $orange_data;
                                $new_data     = $this->getjsondata($event,$result_data,'origin',$logData);  //解析后的数组
                            }else{
                                $change_data  = $logData['change_data'];
                                $change = json_decode($change_data);
                                if(!in_array($data['event'],['EVENT_FORM_CONTENT_REVOKE_UNLOCK','EVENT_FORM_CONTENT_APPLY_UNLOCK']) && empty($change)){
                                    continue;
                                }

                                $result_data['jsonString'] = $change_data;
                                $new_data     = $this->getjsondata($event,$result_data,'current',$logData);  //解析后的数组
                                unset($change_data);
                                unset($change);
                            }
                           /* $new_insert_data = [$check_name, $form_order, $filed_name, $input_value, $update_value, $operate_reason, $event, $create_user, $create_time];
                            $insert_data     = array_merge($insert_data, $new_insert_data);
                            $excelFileObj->checkoutSheet($event_form)->data([$insert_data]);*/

                            if(!empty($new_data)){
                                foreach ($new_data as &$newdata){
                                    $newdata['event_form'] = $event_form;
                                    $newdata['check_name'] = $check_name;
                                    $newdata['form_order'] = $form_order;
                                    $newdata['insert_data'] = $insert_data;
                                    $newdata['create_user'] = SDMHelper::app()->user->getRealName($logData['create_user_id']) . "[" . SDMHelper::app()->user->getRoleNameString($logData['create_user_id'], $logData['sign_id'], $logData['item_id']) . "]";
                                    $res[] = $newdata;
                                }
                            }
                        }
                    }

                    if(!empty($res)){
                        foreach ($res as $value){
                            $event_form  = $value['event_form'];
                            $insert_data = $value['insert_data'];
                            $check_name = !empty($value['check_name']) ? $value['check_name'] : '';
                            $new_insert_data = [$check_name, $value['form_order'], $value['filed_name'], $value['input_value'], $value['update_value'], $value['operate_reason'],$value['event_name'], $value['create_user'], $value['create_time']];
                            $insert      = array_merge($insert_data, $new_insert_data);
                            $excelFileObj->checkoutSheet($event_form)->data([$insert]);
                        }
                    }
                }
            };

            unset($randGroupArr);
            unset($randomNameArr);
            unset($patientDatas);
            unset($patientData);
            unset($itemFormArr);
            unset($itemFormType);
            unset($item_checkName);
            unset($filedSon_arr);
            unset($filedName_arr);
            unset($checktime_datas);
            unset($nochecktime_datas);
            unset($userNameArr);
            unset($itemDatas);
        }

        $filePath = $excelFileObj->output();
    }

    /**
     * Notes:删除文件夹
     * @param
     * @return
     * @author haojinhua
     * @date 2024-05-30
     */
    public function  DelDirHandle($path)
    {
        //如果是目录则继续
        if(is_dir($path)){
            //扫描一个文件夹内的所有文件夹和文件并返回数组
            $p = scandir($path);
            foreach($p as $val){
                //排除目录中的.和..
                if($val !="." && $val !=".."){
                    //如果是目录则递归子目录，继续操作
                    if(is_dir($path.'/'.$val)){
                        //子目录中操作删除文件夹和文件
                        $this->DelDirHandle($path.'/'.$val.'/');
                        //目录清空后删除空文件夹
                        @rmdir($path.'/'.$val.'/');
                    }else{
                        //如果是文件直接删除
                        unlink($path.'/'.$val);
                    }
                }
            }
            rmdir($path);
        }
        return true;
    }

    /**
     * Notes:处理json串的data
     * @param //需处理的json数据
     * @return
     * @author haojinhua
     * @date 2024-04-18
     */
    static function getjsondata($event,$result,$type,$res)
    {
        $group_id          = $result['group_id'];     //是否随机分组表单  2 是 需要另外处理数据
        $jsonString        = $result['jsonString']; //要处理的数组信息
        $filedName_arr     = $result['filedName_arr']; //字段名称数组
        $filedSon_arr      = $result['filedSon_arr']; //父子关系对应数组
        $randGroupArr      = $result['randGroupArr']; //随机分组名称
        $randomNameArr     = $result['randomNameArr']; //随机号数组
        $userNameArr       = $result['userNameArr'];
        $roleNameArr       = $result['roleNameArr'];
        $sig_user_arr      = $result['sig_user_arr'];
        $siguser_role_arr  = $result['siguser_role_arr'];
        $itemsig_arr       = $result['itemsig_arr'];
        $itemData          = $result['itemData'];
        $medicaltakeArr    = $result['medicaltakeArr'];
        $formNameArr       = $result['formNameArr'];
        //$filed_name_string = '';
        $fid               = isset($itemData[$res['item_id']]) && !empty($itemData[$res['item_id']]) ? $itemData[$res['item_id']]['fid'] : '0';
        $form_name         = isset($formNameArr[$res['form_id']]) && !empty($formNameArr[$res['form_id']]) ? $formNameArr[$res['form_id']] : '--';

        $filed_name_arr    = [];

        $data_reason = [];
        $edit_data = json_decode($res['data'], true);
        if(!empty($edit_data) && isset($edit_data['edit_reason']) && !empty($edit_data['edit_reason'])){
            $edit_reasons = json_decode($edit_data['edit_reason'], true);
            if(!empty($edit_reasons)){
                foreach ($edit_reasons as $edit_reason){
                    if (strpos($edit_reason['prop'], '-') !== false) {
                        $edit_reason['prop'] = strstr($edit_reason['prop'], '-', true);
                    }
                    $data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$edit_reason['prop']] = $edit_reason['value'];
                }
            }
        }

        // 解码 JSON 字符串为 PHP 数组
        $data = json_decode($jsonString, true);

        if ($group_id == 2) {
            $processedArray = $data;
        } else {
            // 处理数组 有健为多个_组成的 就截取第一部分的
            $processedArray = array_combine(
                array_map(function ($key) {
                    if (strpos($key, 'normal-type') == false && strpos($key, '-') !== false) {
                        return strstr($key, '-', true);
                    } else {
                        return $key;
                    }
                }, array_keys($data)),
                $data
            );
        }

        $processed = [];
        if(in_array($event,['检查项保存','检查项锁定','检查项解锁','检查项补单'])) {
            if(!empty($data)){
                $checkNameArr = Laminas::$serviceManager->dictionaryCheckname->fetchCol('name','is_del = 0');
                $checkFieldArr = Laminas::$serviceManager->patientFormContentUpdatedLog->getCheckFieldArr();
                foreach($data as $dataKey=>$dataInfo){
                    $filed_name = $input_value = $update_value = '';
                    if($dataKey == 'collect_date'){
                        $filed_name = '采集时间';
                        if ($type == 'current') {  //修改后的数据
                            $input_value = $dataInfo['origin'] == null || $dataInfo['origin'] == '' ? '' : $dataInfo['origin'];
                            $update_value = $dataInfo['current'] == '' || $dataInfo['current'] == null ? '' : $dataInfo['current'];
                        } else {
                            if($dataInfo['current'] !== '' || $dataInfo['current'] !== null){
                                $input_value = $update_value = $dataInfo['current'];
                            }
                        }
                    }elseif(strpos($dataKey,'check_') !== false){
                        $checkname_id = intval(str_replace('check_','',$dataKey));
                        $filed_name = isset($checkNameArr[$checkname_id]) && !empty($checkNameArr[$checkname_id]) ? $checkNameArr[$checkname_id] : '';
                        unset($checkname_id);
                        if(isset($dataInfo['current']) && !empty($dataInfo['current'])){
                            foreach($dataInfo['current'] as $vCurrentKey=>$vCurrentVal){
                                $vCurrentFieldArr = isset($checkFieldArr[$vCurrentKey]) && !empty($checkFieldArr[$vCurrentKey]) ? $checkFieldArr[$vCurrentKey] : [];

                                if(!empty($vCurrentFieldArr)){
                                    $now_update = $vCurrentFieldArr['name'].'【';
                                    if($vCurrentVal == null || $vCurrentVal == ''){
                                        $now_update .= '】';
                                    }else{
                                        //文本
                                        if($vCurrentFieldArr['type'] == 0){
                                            $now_update .= $vCurrentVal.'】';
                                        }
                                        //单选
                                        if($vCurrentFieldArr['type'] == 1){
                                            $vCurrentVal_name = isset($vCurrentFieldArr['select']) && isset($vCurrentFieldArr['select'][$vCurrentVal]) && $vCurrentFieldArr['select'][$vCurrentVal] != '' ? $vCurrentFieldArr['select'][$vCurrentVal] : '';
                                            $now_update .= $vCurrentVal_name.'】';
                                            unset($vCurrentVal_name);
                                        }
                                    }
                                    $update_value .= $now_update.'，';

                                    if ($type == 'current') {  //修改后的数据
                                        $old_val = isset($dataInfo['origin']) && isset($dataInfo['origin'][$vCurrentKey]) && $dataInfo['origin'][$vCurrentKey] != '' ? $dataInfo['origin'][$vCurrentKey] : '';
                                        if ($old_val == null || $old_val == '') {
                                            $input_value .= $vCurrentFieldArr['name'] . '【】，';
                                        } else {
                                            $input_value .= $vCurrentFieldArr['name'] . '【';
                                            //文本
                                            if ($vCurrentFieldArr['type'] == 0) {
                                                $input_value .= $old_val . '】，';
                                            }
                                            //单选
                                            if ($vCurrentFieldArr['type'] == 1) {
                                                $old_vCurrentVal_name = isset($vCurrentFieldArr['select']) && isset($vCurrentFieldArr['select'][$old_val]) && $vCurrentFieldArr['select'][$old_val] != '' ? $vCurrentFieldArr['select'][$old_val] : '';
                                                $input_value .= $old_vCurrentVal_name . '】，';
                                                unset($old_vCurrentVal_name);
                                            }
                                        }
                                        unset($old_val);
                                    }else{
                                        $input_value .= $now_update.'，';
                                    }
                                    unset($now_update);
                                }
                                unset($vCurrentFieldArr);
                            }
                        }
                    }
                    $res_data = $res;
                    $res_data['filed_name']   = $filed_name;
                    $res_data['input_value']  = $input_value != '' ? trim($input_value,'，') : '';
                    $res_data['update_value'] = $update_value != '' ? trim($update_value,'，') : 'NA';  //添加操作无更正值
                    $res_data['operate_reason'] = '';  //操作原因暂时为空
                    $role_name = '后台管理员';
                    if ($res['source'] <> 'PC') {
                        $role_name = '';
                        if ($fid > 0) {
                            $item_id = $fid;
                        }
                        //查询用户角色
                        $user_id     = $res['create_user_id'];
                        $sig_user_id = isset($sig_user_arr[$user_id]) && !empty($sig_user_arr[$user_id]) ? $sig_user_arr[$user_id]['sig_user_id'] : '';
                        $itemsig_id  = $res['sign_id'];
                        $role_ids    = isset($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) && !empty($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) ? $siguser_role_arr[$item_id][$itemsig_id][$sig_user_id] : 0;
                        if(!empty($role_ids)){
                            foreach ($role_ids as $role_id){
                                $role_name .= isset($roleNameArr[$role_id]) && !empty($roleNameArr[$role_id]) ? $roleNameArr[$role_id].'|' : '';
                            }
                        }
                    }

                    $role_name = !empty($role_name) ? trim($role_name,"|"):'';
                    $res_data['create_time']  = date('Y-m-d H:i:s', $res['create_time']);  //操作时间
                    $res_data['create_user']  = isset($userNameArr[$res['create_user_id']]) & !empty($userNameArr[$res['create_user_id']]) ? $userNameArr[$res['create_user_id']] . '【' . $role_name . '】' : ''; //操作人/角色
                    $res_data['event']        = $event;
                    $res_data['id']           = $res['id'];
                    $processed[] = $res_data;
                    unset($data[$dataKey]);
                }
            }
        }elseif (in_array($res['event'],['EVENT_FORM_CONTENT_REVOKE_UNLOCK','EVENT_FORM_CONTENT_APPLY_UNLOCK','EVENT_PATIENT_FORM_ACTIVE','EVENT_PATIENT_FORM_INACTIVE'])){
            $json_data = json_decode($res['json'], true);
            $message  = !empty($json_data['unlock_reason']) ? $json_data['unlock_reason'] : '';
            if(in_array($res['event'],['EVENT_PATIENT_FORM_INACTIVE','EVENT_PATIENT_FORM_ACTIVE'])){
                $message = !empty($edit_data) ? $edit_data['note'] : '';
            }
            $role_name = '后台管理员';
            if ($res['source'] <> 'PC') {
                $role_name = '';
                if ($fid > 0) {
                    $item_id = $fid;
                }
                //查询用户角色
                $user_id     = $res['create_user_id'];
                $sig_user_id = isset($sig_user_arr[$user_id]) && !empty($sig_user_arr[$user_id]) ? $sig_user_arr[$user_id]['sig_user_id'] : '';
                $itemsig_id  = $res['sign_id'];
                $role_ids    = isset($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) && !empty($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) ? $siguser_role_arr[$item_id][$itemsig_id][$sig_user_id] : 0;
                if(!empty($role_ids)){
                    foreach ($role_ids as $role_id){
                        $role_name .= isset($roleNameArr[$role_id]) && !empty($roleNameArr[$role_id]) ? $roleNameArr[$role_id].'|' : '';
                    }
                }
            }

            $role_name = !empty($role_name) ? trim($role_name,"|"):'';
            $res_data['filed_name']   = $form_name;
            $res_data['create_time'] = date('Y-m-d H:i:s', $res['create_time']);  //操作时间
            $res_data['create_user'] = isset($userNameArr[$res['create_user_id']]) & !empty($userNameArr[$res['create_user_id']]) ? $userNameArr[$res['create_user_id']] . '【' . $role_name . '】' : ''; //操作人/角色
            $res_data['event']       = $event;
            $res_data['id']           = $res['id'];
            $res_data['operate_reason'] =$message;
            $processed[]              = $res_data;
        }elseif (in_array($res['event'],['EVENT_MULTI_SHARE_FORM_UPLOAD_IMAGE'])){
            $file_name_string = '';
            $json_data = json_decode($res['data'], true);
            $share_img = json_decode($json_data['share_img'], true);
            if(!empty($share_img)){
                foreach ($share_img as $img){
                    $file_url = $img['url'];
                    $file_name = substr($file_url, strrpos($file_url, '_') + 1);
                    $file_name_string.=$file_name.",";
                }
            }
            $role_name = '后台管理员';

            if ($res['source'] <> 'PC') {
                $role_name = '';
                if ($fid > 0) {
                    $item_id = $fid;
                }
                //查询用户角色
                $user_id     = $res['create_user_id'];
                $sig_user_id = isset($sig_user_arr[$user_id]) && !empty($sig_user_arr[$user_id]) ? $sig_user_arr[$user_id]['sig_user_id'] : '';
                $itemsig_id  = $res['sign_id'];
                $role_ids    = isset($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) && !empty($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) ? $siguser_role_arr[$item_id][$itemsig_id][$sig_user_id] : 0;
                if(!empty($role_ids)){
                    foreach ($role_ids as $role_id){
                        $role_name .= isset($roleNameArr[$role_id]) && !empty($roleNameArr[$role_id]) ? $roleNameArr[$role_id].'|' : '';
                    }
                }
            }

            $role_name = !empty($role_name) ? trim($role_name,"|"):'';
            $file_name_string = rtrim($file_name_string,',');
            $res_data['filed_name']   = '共享图片操作';
            $res_data['input_value']  = $file_name_string;
            $res_data['create_time'] = date('Y-m-d H:i:s', $res['create_time']);  //操作时间
            $res_data['create_user'] = isset($userNameArr[$res['create_user_id']]) & !empty($userNameArr[$res['create_user_id']]) ? $userNameArr[$res['create_user_id']] . '【' . $role_name . '】' : ''; //操作人/角色
            $res_data['event']       = $event;
            $res_data['id']           = $res['id'];
            $processed[]              = $res_data;
        }else{
            // 过滤数组中所有键为数字的
            $result      = array_filter($processedArray, function ($key) {
                return preg_match('/^[^0-9]/', $key) === 0;
            }, ARRAY_FILTER_USE_KEY);
            $res_data    = [];
            $input_value = $update_value = '';
            if ($group_id == 2) {
                if ($fid > 0) {
                    $item_id = $fid;
                }

                //查询项目设置blind_method 是否设盲 是的话随机表单那边只显示 随机号 否则显示随机号+方案分组(药物分组)  注: 药物分组如果没有设置时，就不会展示药物分组， 会显示为:随机号+方案分组。
                $item_blind_method  = isset($itemData[$item_id]) && !empty($itemData[$item_id]) ? $itemData[$item_id]['blind_method'] : '0';

                $arr        = array_keys($result);
                $keys = array_filter($arr, function ($value) {
                    return strpos($value, '-') === false;
                });
                //print_r($result);die;
                if (!empty($keys)) {
                    foreach ($keys as $key) {
                        $old_value = $act_value = $result[$key];
                        if ($type == 'current') {  //修改后的数据
                            $old_value = ($type == 'current') ? $result[$key]['origin'] : $result[$key];
                            $act_value = ($type == 'current') ? $result[$key]['current'] : $result[$key];
                        }

                        $update_value = $type == 'current' ? $act_value : $old_value;
                        $filed_name = isset($filedName_arr[$key]) && !empty($filedName_arr[$key]) ? $filedName_arr[$key]['name'] : '';
                        $var_name   = isset($filedName_arr[$key]) && !empty($filedName_arr[$key]) ? $filedName_arr[$key]['var_name'] : '';
                        $input_value= $old_value;
                        if(in_array($var_name, ['RANGCA', 'RANDOM_GROUP_SYSTEM','RANGC','RANDOM_GROUP_CUSTOM'])){
                            //根据值 查询研究分层表 也就是yikeen_item_randgroup 表
                            $old_value  = isset($randGroupArr[$old_value]) && !empty($randGroupArr[$old_value]) ? $randGroupArr[$old_value] : '';
                            $act_value  = isset($randGroupArr[$act_value]) && !empty($randGroupArr[$act_value]) ? $randGroupArr[$act_value] : '';
                            $update_value = $type == 'current' ? $act_value : $old_value;
                            $input_value = $old_value;
                            if (in_array($var_name, ['RANGCA', 'RANDOM_GROUP_SYSTEM'])) {
                                //系统获取 还需要查询随机号
                                $old_key_value = ($type == 'current') ? $result[$key]['origin'] : $result[$key];
                                $act_key_value = ($type == 'current') ? $result[$key]['current'] : $result[$key];
                                $n_old_key = $old_key_value . '-' . $key . '-' . $old_key_value;
                                $n_act_key = $act_key_value . '-' . $key . '-' . $act_key_value;

                                //获取随机号ID  查询到随机号
                                $old_randomId    = $result[$n_old_key];
                                $act_randomId    = $result[$n_act_key];
                                $old_random_name = isset($randomNameArr[$old_randomId]['randomdetails_name']) && !empty($randomNameArr[$old_randomId]['randomdetails_name']) ? $randomNameArr[$old_randomId]['randomdetails_name'] : '';
                                $act_random_name = isset($randomNameArr[$act_randomId]['randomdetails_name']) && !empty($randomNameArr[$act_randomId]['randomdetails_name']) ? $randomNameArr[$act_randomId]['randomdetails_name'] : '';

                                if (!empty($old_random_name) || !empty($old_random_name)) {
                                    //设盲
                                    $input_value .= $type == 'current' ? '(' . $old_random_name . ')' : '(' . $act_random_name . ')';
                                    $update_value .= $type == 'current' ? '(' . $old_random_name . ')' : '(' . $act_random_name . ')';
                                    if($item_blind_method == 0){
                                        //不设盲
                                        $old_programm_name = isset($randomNameArr[$old_randomId]['random_name']) && !empty($randomNameArr[$old_randomId]['random_name']) ? $randomNameArr[$old_randomId]['random_name'] : '';
                                        $act_programm_name = isset($randomNameArr[$act_randomId]['random_name']) && !empty($randomNameArr[$act_randomId]['random_name']) ? $randomNameArr[$act_randomId]['random_name'] : '';

                                        $old_medication_name = isset($randomNameArr[$old_randomId]['medication_name']) && !empty($randomNameArr[$old_randomId]['medication_name']) ? $randomNameArr[$old_randomId]['medication_name'] : '';
                                        $act_medication_name = isset($randomNameArr[$act_randomId]['medication_name']) && !empty($randomNameArr[$act_randomId]['medication_name']) ? $randomNameArr[$act_randomId]['medication_name'] : '';

                                        $input_value .= !empty($old_medication_name) ? '/'.$old_programm_name.'('.$old_medication_name.')' : '('.$old_medication_name.')';
                                        $update_value .= !empty($act_medication_name) ? '/'.$act_programm_name.'('.$act_medication_name.')' : '('.$act_medication_name.')';
                                    }
                                }
                            }else{
                                //手写随机分组信息查询
                                //根据值 查询研究分层表 也就是yikeen_item_randgroup 表
                                $old_value  = isset($randomArr[$old_value]) && !empty($randomArr[$old_value]) ? $randomArr[$old_value] : '';
                                $act_value  = isset($randomArr[$act_value]) && !empty($randomArr[$act_value]) ? $randomArr[$act_value] : '';
                                $update_value = $type == 'current' ? $act_value : $old_value;
                                $input_value = $old_value;
                                //系统获取 还需要查询随机号
                                $old_key_value = ($type == 'current') ? $result[$key]['origin'] : $result[$key];
                                $act_key_value = ($type == 'current') ? $result[$key]['current'] : $result[$key];
                                $n_old_key = $old_key_value . '-' . $key . '-' . $old_key_value;
                                $n_act_key = $act_key_value . '-' . $key . '-' . $act_key_value;
                                //查询到填写的随机号
                                $old_random    = $result[$n_old_key];
                                $act_random    = $result[$n_act_key];
                                if ($type == 'current') {
                                    $old_random    = $result[$n_old_key]['origin'];
                                    $act_random    = $result[$n_act_key]['current'];
                                }
                                $input_value   = !empty($old_random) ? $old_value.'('.$old_random.')':$old_value;
                                $update_value  = !empty($act_random) ? $act_value.'('.$act_random.')':$act_value;
                            }
                        }

                        $res_data['filed_name']   = $filed_name;
                        $res_data['input_value']  = $input_value;
                        $res_data['update_value'] = $event <> '添加表单' && !empty($update_value) ? $update_value : 'NA';  //添加操作无更正值
                        $operate_reason = isset($data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$edit_reason[$key]])&&!empty($data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$edit_reason[$key]]) ? $data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$edit_reason[$key]] : '';
                        $res_data['operate_reason'] = $operate_reason;  //操作原因暂时为空

                        $role_name = '后台管理员';

                        if ($res['source'] <> 'PC') {
                            $role_name = '';
                            if ($fid > 0) {
                                $item_id = $fid;
                            }
                            //查询用户角色
                            $user_id     = $res['create_user_id'];
                            $sig_user_id = isset($sig_user_arr[$user_id]) && !empty($sig_user_arr[$user_id]) ? $sig_user_arr[$user_id]['sig_user_id'] : '';
                            $itemsig_id  = $res['sign_id'];
                            $role_ids    = isset($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) && !empty($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) ? $siguser_role_arr[$item_id][$itemsig_id][$sig_user_id] : 0;
                            if(!empty($role_ids)){
                                foreach ($role_ids as $role_id){
                                    $role_name .= isset($roleNameArr[$role_id]) && !empty($roleNameArr[$role_id]) ? $roleNameArr[$role_id].'|' : '';
                                }
                            }
                        }

                        $role_name = !empty($role_name) ? trim($role_name,"|"):'';
                        $res_data['create_time'] = date('Y-m-d H:i:s', $res['create_time']);  //操作时间
                        $res_data['create_user'] = isset($userNameArr[$res['create_user_id']]) & !empty($userNameArr[$res['create_user_id']]) ? $userNameArr[$res['create_user_id']] . '【' . $role_name . '】' : ''; //操作人/角色
                        $res_data['event']       = $event;
                        $res_data['id']           = $res['id'];
                        $processed[]              = $res_data;
                    }
                }
            } else {
                // 使用array_keys函数获取所有的键值
                $keys        = array_keys($result);
                $new_key_arr = array();
                if (!empty($keys)) {
                    $arr = [
                        '1' => '正常',
                        '2' => 'CS',
                        '3' => 'NCS',
                    ];
                    foreach ($keys as $key) {
                        $isnormal = false;
                        if (stripos($key, 'normal-type') !== false) {
                            $old_key = $key;
                            //说明是异常值判断日志
                            $key = strstr($key, '-', true);
                            $isnormal = true;
                        }
                        $filed_name           = isset($filedName_arr[$key]) && !empty($filedName_arr[$key]) ? $filedName_arr[$key]['name'] : '';
                        $filed_type           = isset($filedName_arr[$key]) && !empty($filedName_arr[$key]) ? $filedName_arr[$key]['type'] : '';
                        $var_name             = isset($filedName_arr[$key]) && !empty($filedName_arr[$key]) ? $filedName_arr[$key]['var_name'] : '';
                        $filed_name_arr[$key] = $filed_name;
                        if ($type == 'current') {  //修改后的数据
                            if($isnormal){
                                $filed_name .='-异常值判断';
                                $oldvalue = ($type == 'current') ? $result[$old_key]['origin'] : $result[$old_key];
                                $actvalue = ($type == 'current') ? $result[$old_key]['current'] : $result[$old_key];
                                $old_value = $arr[$oldvalue];
                                $act_value = $arr[$actvalue];
                            }else{
                                $old_value = ($type == 'current') ? $result[$key]['origin'] : $result[$key];
                                $act_value = ($type == 'current') ? $result[$key]['current'] : $result[$key];
                                if(in_array($filed_type,[13,14,19]) && (!empty($old_value) || !empty($act_value))){
                                    //截取图片URL中的最后一个_后面的信息
                                    if(!empty($old_value)){
                                        $old_value  = json_decode($old_value, true) ? json_decode($old_value, true) : $old_value;
                                        $old_file_url = $old_value[0]['url'];
                                        $old_file_name = substr($old_file_url, strrpos($old_file_url, '_') + 1);
                                    }
                                    if(!empty($act_value)){
                                        $n_act_value = json_decode($act_value, true) ? json_decode($act_value, true) : $act_value;
                                        if(count($n_act_value) > 1){
                                            $act_file_url = $n_act_value[1]['url'];
                                            $act_file_name = substr($act_file_url, strrpos($act_file_url, '_') + 1);
                                        }else{
                                            $act_file_url = $n_act_value[0]['url'];
                                            $act_file_name = substr($act_file_url, strrpos($act_file_url, '_') + 1);
                                        }
                                    }
                                }
                            }

                        } else {
                            if($isnormal){
                                $filed_name .='-异常值判断';
                                $oldvalue = $actvalue = $result[$old_key];
                                $old_value = $arr[$oldvalue];
                                $act_value = $arr[$actvalue];
                            }else{
                                $old_value = $act_value = $result[$key];
                                if(in_array($filed_type,[13,14,19]) && (!empty($old_value) || !empty($act_value))){
                                    //截取图片URL中的最后一个_后面的信息
                                    if(!empty($old_value)){
                                        $n_old_value = json_decode($old_value, true) ? json_decode($old_value, true) : $old_value;
                                        $old_file_url = $n_old_value[0]['url'];
                                        $old_file_name = substr($old_file_url, strrpos($old_file_url, '_') + 1);
                                    }

                                    if(!empty($act_value)){
                                        $n_act_value = json_decode($act_value, true) ? json_decode($act_value, true) : $act_value;
                                        $act_file_url = $n_act_value[0]['url'];
                                        $act_file_name = substr($act_file_url, strrpos($act_file_url, '_') + 1);
                                    }

                                    //echo $old_file_name."====".$act_file_name;
                                }
                            }
                        }
                        if($filed_type == 10){
                            if($var_name == 'CM' || $var_name == 'CMINDC100'){
                                //查询【yikeen_collect_medicaltake】take_type ==6 的数据  2024-10-21 补充
                                $old_value = isset($medicaltakeArr[$old_value]) && !empty($medicaltakeArr[$old_value]) ? $medicaltakeArr[$old_value] : '';
                                $act_value = isset($medicaltakeArr[$act_value]) && !empty($medicaltakeArr[$act_value]) ? $medicaltakeArr[$act_value] : '';
                            }else{
                                $old_value = isset($filedSon_arr[$key][(int)$old_value]) && !empty($filedSon_arr[$key][(int)$old_value]) ? $filedSon_arr[$key][(int)$old_value]['name'] : '';
                                $act_value = isset($filedSon_arr[$key][(int)$act_value]) && !empty($filedSon_arr[$key][(int)$act_value]) ? $filedSon_arr[$key][(int)$act_value]['name'] : '';
                            }
                        }elseif (in_array($filed_type, [11, 12])) {
                            $old_value = isset($filedSon_arr[$key][(int)$old_value]) && !empty($filedSon_arr[$key][(int)$old_value]) ? $filedSon_arr[$key][(int)$old_value]['name'] : '';
                            $act_value = isset($filedSon_arr[$key][(int)$act_value]) && !empty($filedSon_arr[$key][(int)$act_value]) ? $filedSon_arr[$key][(int)$act_value]['name'] : '';
                        } elseif (in_array($filed_type, [13, 14])) {
                            $old_value = empty($old_value) ? '未上传图片/文件' : '已上传图片/文件('.$old_file_name.')';
                            $act_value = empty($act_value) ? '未上传图片/文件' : '已上传图片/文件('.$act_file_name.')';
                        } elseif ($filed_type == 19) {
                            $old_value = empty($old_value) ? '未上传图片' : '已上传图片('.$old_file_name.')';
                            $act_value = empty($act_value) ? '未上传图片' : '已上传图片('.$act_file_name.')';
                        }

                        switch ($var_name) {
                            case 'CHECKIMG ':
                                //如果内容是“[]”则显示“未上传图片”，反之 显示“已上传图片”
                                $old_value = empty($old_value) ? '未上传图片' : '已上传图片('.$old_file_name.')';
                                $act_value = empty($act_value) ? '未上传图片' : '已上传图片('.$act_file_name.')';
                                break;
                            case 'OUTPLANCHECK ':
                            case 'OPCH ':
                                //字段变量名 == OUTPLANCHECK || OPCH 时进行判断，如果内容是“[]”显示“无”，反之 显示“有”
                                $old_value = empty($old_value) ? '无' : '有';
                                $act_value = empty($act_value) ? '无' : '有';
                                break;
                        }

                        if (!empty($filed_name)) {
                            if ($type == 'current') {
                                /*$input_value = '【'.$filed_name.'】:'.$old_value;
                                $update_value = '【'.$filed_name.'】:'.$act_value;*/
                                $input_value  = $old_value;
                                $update_value = $act_value;
                            } else {
                                //拼接字符串
                                // $input_value = '【'.$filed_name.'】:'.$act_value;
                                $input_value = $act_value;
                            }
                        }
                        $res_data = $res;
                        $res_data['filed_name']   = $filed_name;
                        $res_data['input_value']  = $input_value;
                        $res_data['update_value'] = $event <> '添加表单' && !empty($update_value) ? $update_value : '';  //添加操作无更正值
                        $operate_reason = isset($data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$key])&&!empty($data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$key]) ? $data_reason[$res['checktime_id']][$res['form_id']][$res['patient_id']][$key] : '';
                        $res_data['operate_reason'] = $operate_reason;  //操作原因暂时为空

                        $role_name = '后台管理员';
                        if ($res['source'] <> 'PC') {
                            $role_name = '';
                            if ($fid > 0) {
                                $item_id = $fid;
                            }
                            //查询用户角色
                            $user_id     = $res['create_user_id'];
                            $sig_user_id = isset($sig_user_arr[$user_id]) && !empty($sig_user_arr[$user_id]) ? $sig_user_arr[$user_id]['sig_user_id'] : '';
                            $itemsig_id  = $res['sign_id'];
                            $role_ids    = isset($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) && !empty($siguser_role_arr[$item_id][$itemsig_id][$sig_user_id]) ? $siguser_role_arr[$item_id][$itemsig_id][$sig_user_id] : 0;
                            if(!empty($role_ids)){
                                foreach ($role_ids as $role_id){
                                    $role_name .= isset($roleNameArr[$role_id]) && !empty($roleNameArr[$role_id]) ? $roleNameArr[$role_id].'|' : '';
                                }
                            }
                        }

                        $role_name = !empty($role_name) ? trim($role_name,"|"):'';
                        $res_data['create_time']  = date('Y-m-d H:i:s', $res['create_time']);  //操作时间
                        $res_data['create_user']  = isset($userNameArr[$res['create_user_id']]) & !empty($userNameArr[$res['create_user_id']]) ? $userNameArr[$res['create_user_id']] . '【' . $role_name . '】' : ''; //操作人/角色
                        $res_data['event_name']   = $event;
                        $res_data['id']           = $res['id'];
                        $processed[] = $res_data;
                    }
                }

            }
        }
        unset($data_reason);
        return $processed;
    }


    /*
     * yield处理数组循环，防止内存溢出
     */
    public static function yieldFuc(&$logDatas, &$oper_type_data, &$log_type_data, &$sysUserNameDatas)
    {
        foreach ($logDatas as $key => &$logData) {
            $logData['create_time'] = date('Y-m-d H:i:s', $logData['create_time']);
            $logData['user_realname'] = $sysUserNameDatas[$logData['user_id']];
            $logData['oper_type_title'] = $oper_type_data[$logData['oper_type']];
            $logData['log_type_title'] = $log_type_data[$logData['log_type']];
            unset($logDatas[$key]);
            yield $logData;

        }
    }

    /*
     * 通过yield从数据库中分批取出数据，也是为了防止数据量过大一次性抓取数据，导致内存溢出的情况
     */
    public function yieldDbData($page, $syslogWhere)
    {
        $limit = 100000;
        for ($i = 1; $i <= $page; $i++) {
            $offset = ($i - 1) * ($limit + 1);
            $logDatas = $this->LocalService()->adminLog->fetchAll([
                'where' => $syslogWhere,
                'columns' => ['user_id', 'create_time', 'log_ip', 'event_from', 'oper_type', 'log_type', 'change_data', 'log_remark', 'new_data'],
                'order' => ['create_time'],
                'limit' => $limit,
                'offset' => $offset
            ]);
            yield $logDatas;
        }
    }

    public function yieldformDbData($page, $syslogWhere)
    {
        $limit = 100000;
        for ($i = 1; $i <= $page; $i++) {
            $offset = ($i - 1) * ($limit + 1);
            $logDatas = $this->LocalService()->patientFormContentUpdatedLog->fetchAll([
                'where'=>$syslogWhere,
                'columns'=>['id','item_id','checktime_id','form_id','patient_id','create_user_id','create_time','data','content_id','source','event','change_data','sign_id','json'],
                'order'=>['create_time desc'],
                'limit'=>$limit,
                'offset'=>$offset
            ]);
            //echo "<pre>";print_r($logDatas);die;
            yield $logDatas;
        }
    }

    /**
     * Notes : 化验单指标结果-横表
     * @param $data
     * Author:唐伯虎不虎
     */
    public function downformfileocrcsae($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $create_time = $data['create_time'];       //创建时间
        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);
        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, 10);

        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            new Operator('checklist_id', Operator::OP_GT, 0),
        ];

        $whereArr['columns'] = ['id', 'name', 'code', 'checklist_id', 'var_name'];

        $formDatas = $this->LocalService()->itemForm->fetchAll($whereArr);


        $checklistWhere = [
            'item_id' => $item_id,
            'is_del' => 0,
            new Operator('checklist_id', Operator::OP_GT, 0),
        ];

        $checklistdata = $this->LocalService()->itemForm->fetchCol('checklist_id', $checklistWhere);

        $checklistdatastr = implode(',', $checklistdata);
        //获取当前项目下符合条件的检查分类以及检查项
        $checknameData = $this->getItemcheckname($item_id, $checklistdatastr);
        //检查项分类
        $categoryDatas = $checknameData['categoryDatas'];

        //检查项
        $checknameDatas = $checknameData['checknameDatas'];

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        foreach ($formDatas as $cateKk => $cateV) {
            $cateK = $cateV['checklist_id'];

            $catalogue[99 + $cateK][] = $cateV['name'];
            $catalogue[99 + $cateK][] = $cateV['var_name'];
            //表头
            $data = [
                ['中心编号', '筛选号', '受试者姓名']
            ];

            //检查项表头
            foreach ($checknameDatas[$cateK] as $k => $v) {
                //循环检查点
                foreach ($checktimeDatas as $key => $value) {
                    $data[0][] = $v['name'] . '-' . $value['check_name'];
                }
            }
            $dataKey = 1;
            //中心
            foreach ($itemsignatoryDatas as $key => $val) {

                //循环受试者
                foreach ($patientDatas[$val['value']] as $patientK => $patientV) {


                    //循环中心获取中心缓存文件数v据
                    $applyfilepath = APP_PATH . '/data/itemIdentificationResult/' . $item_id . '/' . $val['value'] . '/' . $item_id . '-' . $val['value'] . '-' . $patientV['id'] . '.txt';

                    //数据集
                    $result = json_decode(file_get_contents($applyfilepath, 0), true);


                    // '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '是否完成', '采集日期'
                    $data[$dataKey][] = $val['number'];
                    //筛选号
                    $data[$dataKey][] = $patientV['patient_number'];
                    //受试者姓名
                    $data[$dataKey][] = $patientV['patient_name'];
                    //循环项目中检查项设置
                    foreach ($checknameDatas[$cateK] as $checknameK => $checknameV) {

                        //循环检查点
                        foreach ($checktimeDatas as $checkK => $checkV) {
                            // 检查点 --分类 --指标 数据不存在 退出
                            if (empty($result[$checkV['id']][$cateV['id']])) {
                                $data[$dataKey][] = '--';
                                continue;
                            }
                            //是否匹配成功开关，如果未匹配成功则录入空
                            $falg = 0;
                            foreach ($result[$checkV['id']][$cateV['id']] as $kk => $vv) {
                                if ($checknameV['checkname_id'] == $vv['checkname_id']) {
                                    $falg = 1;

                                    //测量结果
                                    $data[$dataKey][] = $vv['result'];

                                    break;
                                }
                            }
                            if ($falg == 0) {
                                $data[$dataKey][] = '--';
                            }
                        }
                    }
                    ++$dataKey;
                }
            }
            //将数据存入数组
            $formname = str_replace("/", '-', $cateV['name']);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);

            $formData[$formname] = $data;
        }

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] . '化验单指标结果' . '-' . $create_time . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header(['表单名称', '表单变量名'])->data($catalogue);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //循环指标数据生成sheet
        foreach ($formData as $k => $v) {
            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }
            $fileObject->addSheet($sheetName)->data($formData[$k]);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }

        //输出数据
        $filePath = $fileObject->output();

    }

    /**
     * Notes : 研究中心信息
     * @param $data
     * Author:唐伯虎不虎
     */
    public function researchcenter($data)
    {
        $item_id = $data['item_id'];
        $create_time = $data['create_time'];       //创建时间
        //获取中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo(0, $item_id, 0);
        $signhandle = [];
        foreach($itemsignatoryDatas as $k=>$v){
            $signhandle[$v['value']] = $v;
        }
        $header = ['序号', '研究中心', '中心编号'];

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number', 'fid'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        //获取当前项目的角色
        $roleWhere['where'] = [
            'item_id' => $itemInfo['fid'],
            'is_del' => 0,
            'status' => 0,
        ];
        $roleWhere['columns'] = ['id', 'role_name'];
        $roleWhere['order'] = "sort";
        $realroleDatas = $this->LocalService()->realRole->fetchAll($roleWhere);
        $roleData = [];
        foreach ($realroleDatas as $k => $v) {
            $header[] = $v['role_name'];
            $roleData[$v['id']] = $v['role_name'];
        }
        $header[] = '排序号';
        $header[] = '备注';
        $data = [];

        //获取各中心各角色下的人员
        $roleSiguserData = $this->LocalService()->itemSignatory->getRoleSiguser($itemInfo['fid'], 0, self::sigFormRolePrefix);
        foreach ($itemsignatoryDatas as $itemsigDataKey => $itemsigData) {
            $dataKey = $itemsigDataKey + 1;
            //序号
            $data[$dataKey][] = $dataKey;
            $info[$dataKey][] = $dataKey;
            //研究中心
            $data[$dataKey][] = $itemsigData['label'];
            $info[$dataKey][] = $itemsigData['label'];
            //中心编号
            $data[$dataKey][] = $itemsigData['number'];
            $info[$dataKey][] = $itemsigData['number'];

            //角色信息
            if (!empty($roleSiguserData[$itemsigData['value']])) {
                $realroleUser = [];
                foreach ($roleSiguserData[$itemsigData['value']] as $roleK => &$roleSiguserDatum) {
                    $roleSiguserDatum = array_unique($roleSiguserDatum);

                    $roleSiguserDatum = implode('、', $roleSiguserDatum);
                    $realroleUser[$itemsigData['value']][substr($roleK, 8)] = $roleSiguserDatum;
                }
            }

            foreach ($realroleDatas as $k => $v) {
                if (!empty($realroleUser[$itemsigData['value']][$v['id']])) {
                    $data[$dataKey][] = $realroleUser[$itemsigData['value']][$v['id']];
                } else {
                    $data[$dataKey][] = '';
                }
            }
            $data[$dataKey][] = $itemsigData['order'];
            $data[$dataKey][] = $itemsigData['remark'];
        }

        $roledata = $this->LocalService()->roleSignatoryRelation->fetchAll(
            [
                'where'=> [
                    'item_id' => $itemInfo['fid'],
                    'is_del' => 0,
                    'status' => 0,
                    new Operator('signatory_user', Operator::OP_GT, 0),
                ],
                'order'=>['item_sign_id','role_id']
            ]
        );
        $roleuser = $this->LocalService()->roleSignatoryRelation->fetchCol('signatory_user',[
            'item_id' => $itemInfo['fid'],
            'is_del' => 0,
            'status' => 0,
            new Operator('signatory_user', Operator::OP_GT, 0),
        ]);

        $signuser_name = $this->LocalService()->signatoryUser->fetchCol('user_name',[
            'is_del' => 0,
            'id' => $roleuser,
        ]);
        $signuser_tel = $this->LocalService()->signatoryUser->fetchCol('user_tel',[
            'is_del' => 0,
            'id' => $roleuser,
        ]);
        $info = [['序号','研究中心','中心编号','角色名称','联系人','联系方式']];
        foreach($roledata as $key=>$value){
            $dataKey = $key + 1;
            //序号
            $info[$dataKey][] = $dataKey;
            //研究中心
            $info[$dataKey][] = $signhandle[$value['item_sign_id']]['label'];
            //中心编号
            $info[$dataKey][] = $signhandle[$value['item_sign_id']]['number'];
            //角色名称
            $info[$dataKey][] = $roleData[$value['role_id']];
            //联系人
            $info[$dataKey][] = $signuser_name[$value['signatory_user']];
            //联系方式
            $info[$dataKey][] = $signuser_tel[$value['signatory_user']];
        }


        $item_name = $this->LocalService()->itemInfo->getOneFieldVal('name', [
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $item_name . '-' . $create_time . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '研究中心数据');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header($header)->data($data);
        $fileObject->setRow('A1:C1', 20, $headerBgStyle)->setColumn('A1:C1', 20);
        $fileObject->setRow('D1:I1', 20, $headerBgStyle)->setColumn('D1:I1', 80);
        $fileObject->addSheet('具体信息')->data($info);
        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes : 盲态判读结果
     * @param $data
     * Author:唐伯虎不虎
     * Date:2024/5/13 14:49
     */
    public function score($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $patient_status = $data['patient_status'] ?: '10';       //受试者脱离完成状态
        $form_ids = $data['form_ids'] ?: '0';       //表单ID
        $create_time = $data['create_time'];       //创建时间
        $pater = $data['pater'];       //创建时间


        //当前项目阶段

        $StageDatas = $this->getItemstage($item_id);

        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, $patient_status);

        //不同用户的填写数据。【包括评分员和评分管理员所填数据】
        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
            'is_using_score' => 1,
        ];
        if ($form_ids != 0) $whereArr['where']['id'] = explode(',', $form_ids);
        $whereArr['columns'] = ['id', 'name', 'type', 'code', 'rdg_type', 'group_id', 'checklist_id', 'var_name'];
        $whereArr['order'] = 'order';
        $data = $this->LocalService()->itemForm->fetchAll($whereArr);
        $formdata = [];
        $formidArr = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $formidArr[] = $v['id'];
                $formdata[$v['id']] = $v;
            }
        }

        $form_ids = implode(',', $formidArr);

        //获取当前申请的表单
        $form = $this->getform($item_id, $form_ids);

        //查询受试者填写表单数据
        $patientformDatas = $this->getpatientform($item_id, $patient_id, $form_ids, $itemsig_id, $pater,1,0);

        //获取表单字段类型为单选/多选的数据
        $optionDatas = $this->getformoptions($item_id, $form_ids);

        //处理中心
        foreach ($itemsignatoryDatas as $k => $v) {
            $itemsignatoryDatas[$v['value']] = $v;
            unset($itemsignatoryDatas[$k]);
        }
        $formfieldDatas = $this->getformrules($item_id, $form_ids);

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        //查询当前项目分配评分人、评分管理员的角色
        $fid = $this->LocalService()->itemInfo->getOneFieldVal('fid', [
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称

        $patermenuId = $this->LocalService()->adminMenu->getOneFieldVal('id', [
            'is_del' => 0,
            'menu_name' => '评分',
        ]);
        $pateradminId = $this->LocalService()->adminMenu->getOneFieldVal('id', [
            'is_del' => 0,
            'menu_name' => '评分管理员'
        ]);

        $datas = $this->LocalService()->realRolemodulerelation->fetchAll(
            [
                'where' => [
                    'module_id' => $patermenuId,
                    'status' => 0,
                    'item_id' => $fid,
                ],
                'columns' => ['role_id'],
            ]
        );
        $pater = array_column($datas, 'role_id'); //评分人员

        $datas = $this->LocalService()->realRolemodulerelation->fetchAll(
            [
                'where' => [
                    'module_id' => $pateradminId,
                    'status' => 0,
                    'item_id' => $fid,
                ],
                'columns' => ['role_id'],
            ]
        );
        $paterAdmin = array_column($datas, 'role_id'); //评分人员


        $header_prefix = [['INVSITE', 'PT', 'SUBNAM', 'CPEVENT', 'FORM_SEQ', '', '', ''], ['项目ID', '中心编号', '筛选号', '受试者姓名', '访视名称', '表单序号', '操作人', '角色授权']];

        foreach ($form as $key => $value) {
            //查询是否是分值表单
            $radio['where'] = [
                'is_score' => 1,
                'form_id' => $value['id'],
            ];
            $radio['columns'] = ['id'];
            $radio_score = $this->LocalService()->itemFormFieldRadio->fetchOne($radio);
            $is_score = 0; //不是分值表单

            $sheetData = [];
            if (!empty($radio_score)) {
                $sheetData[0][] = '';
                $sheetData[1][] = '分值';
                $is_score = 1; //是分值表单
            }
            //如果此表单没有字段 则直接退出 [非实验总结类表单]
            if (empty($formfieldDatas[$value['id']])) continue;

            $sheetData[0] = array_merge($header_prefix[0], $formfieldDatas[$value['id']]['var_name']);
            $sheetData[1] = array_merge($header_prefix[1], $formfieldDatas[$value['id']]['name']);

            if (empty($attrnumber)) {
                unset($sheetData[0][2], $sheetData[1][2]);
            }

            if (empty($attrname)) {
                unset($sheetData[0][3], $sheetData[1][3]);
            }

            $sheetData[0] = array_values($sheetData[0]);
            $sheetData[1] = array_values($sheetData[1]);
            //受试者数据
            $patientformcontent = $patientformDatas[$value['id']];

            $eCRF[$key][] = $value['name'];
            $eCRF[$key][] = $value['var_name'];

            //写入大数组
            $formname = str_replace("/", '-', $value['name']);
            $formname = str_replace("[", '【', $formname);
            $formname = str_replace("]", '】', $formname);
            $formname = str_replace("？", '', $formname);
            $formname = str_replace("（", '【', $formname);
            $formname = str_replace("）", '】', $formname);
            $formname = str_replace(" ", '', $formname);

            //如果当前表单没有受试者填写 则直接退出
            if (empty($patientformcontent)) {
                $formDatas[$formname] = $sheetData;
            }
            if (!empty($patientformcontent)) {
                //排序数据
                $dataOrder = [];

                //数组Key
                $dataOrder_id = [];
                //数据数组
                $data = [];
                foreach ($patientformcontent as $contentKey => $contentVal) {

                    $patient_id = $contentVal['patient_id'];
                    //已删除受试者直接跳出
                    if (empty($patientDatas[$contentVal['itemsig_id']][$patient_id])) continue;

                    $dataOrder[$contentVal['id']]['patient_id'] = $patient_id;
                    $dataOrder[$contentVal['id']]['id'] = $contentVal['id'];
                    //排序值处理
                    $dataOrder[$contentVal['id']]['sign'] = $itemsignatoryDatas[$contentVal['itemsig_id']]['order'];
                    $dataOrder[$contentVal['id']]['patient'] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['order'];

                    if (!in_array($value['group_id'], [3, 5])) {
                        $dataOrder[$contentVal['id']]['checktime'] = $checktimeDatas[$contentVal['checktime_id']]['order'];
                        if ($checktimeDatas[$contentVal['checktime_id']]['stage_id'] != 0) {
                            $dataOrder[$contentVal['id']]['stage'] = $StageDatas[$checktimeDatas[$contentVal['checktime_id']]['stage_id']]['order'];
                        } else {
                            $dataOrder[$contentVal['id']]['stage'] = 0;
                        }
                    }

                    $dataOrderKey = $itemsignatoryDatas[$contentVal['itemsig_id']]['order'] . '-' . $patientDatas[$contentVal['itemsig_id']][$patient_id]['order'] . '-' . $dataOrder[$contentVal['id']]['checktime'] . '-' . $dataOrder[$contentVal['id']]['stage'] . '-' . $dataOrder[$contentVal['id']]['id'];

                    if ($value['type'] == 1 || $value['group_id'] == 10 || $value['group_id'] == 11 || $value['group_id'] == 3 || $value['group_id'] == 5) $dataOrderKey .= "-" . $contentKey;

                    $dataKey = $contentKey + 2;

                    $dataOrder_id[$dataOrderKey] = $dataKey;


                    //项目ID
                    $data[$dataKey][] = $itemInfo['number'];

                    //中心编号
                    $data[$dataKey][] = $itemsignatoryDatas[$contentVal['itemsig_id']]['number'];

                    if (!empty($attrnumber)) {
                        //受试者编号
                        $data[$dataKey][] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['patient_number'];
                    }


                    if (!empty($attrname)) {
                        //受试者姓名
                        $data[$dataKey][] = $patientDatas[$contentVal['itemsig_id']][$patient_id]['patient_name'];
                    }


                    //访视名称
                    if (!in_array($value['group_id'], [3, 5])) {
                        $checktimeName = $checktimeDatas[$contentVal['checktime_id']]['check_name'];

                        $dataOrder[$contentVal['id']]['checktime'] = $checktimeDatas[$contentVal['checktime_id']]['order'];

                        if ($checktimeDatas[$contentVal['checktime_id']]['stage_id'] != 0) {
                            $data[$dataKey][] = $checktimeName . '-' . $StageDatas[$checktimeDatas[$contentVal['checktime_id']]['stage_id']]['stage_name'];
                            $dataOrder[$contentVal['id']]['stage'] = $StageDatas[$checktimeDatas[$contentVal['checktime_id']]['stage_id']]['order'];
                        } else {
                            $data[$dataKey][] = $checktimeName;
                            $dataOrder[$contentVal['id']]['stage'] = 0;
                        }
                    }

                    //表单序号 默认值
                    $data[$dataKey][] = 1;

                    //评分人
                    $data[$dataKey][] = $this->LocalService()->adminUser->getOneFieldVal('realname', [
                        'is_del' => 0,
                        'id' => $contentVal['create_user_id'],
                    ]);//获取项目名称

                    //角色授权
                    $pater_mobile = $this->LocalService()->adminUser->getOneFieldVal('mobile', [
                        'is_del' => 0,
                        'id' => $contentVal['create_user_id'],
                    ]);//获取项目名称

                    $pater_id = $this->LocalService()->signatoryUser->getOneFieldVal('id', [
                        'is_del' => 0,
                        'user_tel' => $pater_mobile,
                    ]);//获取项目名称


                    $role = $this->LocalService()->roleSignatoryRelation->fetchAll(['where' => [
                        'item_id' => $fid,
                        'status' => 0,
                        'is_del' => 0,
                        'signatory_user' => $pater_id,
                    ], 'columns' => ['role_id']]);

                    $p = '';
                    $p_a = '';
                    if (!empty($role)) {
                        foreach ($role as $roleK => $roleV) {
                            if ($p == '' && in_array($roleV['role_id'], $pater)) $p = '评分人员';
                            if ($p_a == '' && in_array($roleV['role_id'], $paterAdmin)) $p_a = '评分管理员';
                        }
                    }
                    if (!empty($p) && !empty($p_a)) {
                        $data[$dataKey][] = $p . ' ' . $p_a;
                    } elseif (!empty($p)) {
                        $data[$dataKey][] = $p;
                    } elseif (!empty($p_a)) {
                        $data[$dataKey][] = $p_a;
                    } else {
                        $data[$dataKey][] = '';
                    }

                    //数据主题
                    $patientformContent = json_decode($contentVal['data'], true);
                    //处理数据含有“-”符号，截取符号前的ID
                    foreach ($patientformContent as $contentK => $contentV) {
                        if (count(explode('-', $contentK)) > 1) {
                            $arr = explode('-', $contentK);
                            $arrCount = count($arr);
                            $unsetNumber = $arrCount - ceil($arrCount / 2) + 1;

                            for ($i = 1; $i < $unsetNumber; $i++) {
                                unset($arr[count($arr) - 1]);
                            }

                            $str = implode('-', $arr);

                            $patientformContent[$str] = $contentV;
                        }
                    }

                    //分值表单
                    if ($is_score == 1) {
                        if (isset($patientformContent['score'])) {
                            $data[$dataKey][] = $patientformContent['score'];
                        } else {
                            $data[$dataKey][] = [];
                        }
                    }
                    $formfield = $formfieldDatas[$value['id']]['data'];
                    //处理表单字段
                    foreach ($formfield as $fieldKey => $fieldVal) {

                        $resultKey = $fieldVal['patents'];

                        if (!isset($patientformContent[$resultKey])) {
                            $data[$dataKey][] = '';
                            continue;
                        }

                        if ($fieldVal['var_name'] == 'CHECKIMG') {
                            if ($patientformContent[$resultKey] != '[]') {
                                $data[$dataKey][] = '已上传图片';
                            } else {
                                $data[$dataKey][] = '未上传图片';
                            }
                            continue;
                        }

                        if ($fieldVal['var_name'] == 'OUTPLANCHECK') {
                            if ($patientformContent[$resultKey] == '[]') {
                                $data[$dataKey][] = '无';
                            } else {
                                $data[$dataKey][] = '有';
                            }
                            continue;
                        }

                        if ($fieldVal['type'] == 10 || $fieldVal['type'] == 12) {
                            $data[$dataKey][] = $optionDatas[$fieldVal['id']][$patientformContent[$resultKey]];
                        } elseif ($fieldVal['type'] == 11) {
                            if (!is_array($patientformContent[$resultKey])) {
                                $options = explode(',', $patientformContent[$resultKey]);
                            } else {
                                $options = $patientformContent[$resultKey];
                            }
                            $optionResult = [];
                            foreach ($options as $optionKey => $optionVal) {
                                $optionResult[] = $optionDatas[$fieldVal['id']][$optionVal];
                            }
                            $data[$dataKey][] = implode(',', $optionResult);
                        } elseif ($fieldVal['type'] == 13 || $fieldVal['type'] == 14) {
                            if (!empty($patientformContent[$resultKey]) && $patientformContent[$resultKey] != '[]') {
                                $data[$dataKey][] = '已上传图片/文件';
                            } else {
                                $data[$dataKey][] = [];
                            }
                        } else {
                            $data[$dataKey][] = $patientformContent[$resultKey];
                        }
                    }
                }

                $O1 = [];
                $O2 = [];
                $O3 = [];
                $O4 = [];
                $O6 = [];

                //数组排序
                foreach ($dataOrder as $k => $v) {
                    $O1[$k] = $v['sign'];
                    $O2[$k] = $v['patient'];
                    $O3[$k] = $v['stage'];
                    $O4[$k] = $v['checktime'];
                    $O4[$k] = $v['id'];
                    //一对多表单
                    if ($value['type'] == 1) {
                        $O5[$k] = $v['type'];
                    }
                }

                if ($value['type'] == 0) {
                    array_multisort($O1, $O2, $O3, $O4, $dataOrder);
                } else {
                    array_multisort($O1, $O2, $O3, $O4, $dataOrder);
                }
                if (!in_array($value['group_id'], [3, 5])) {
                    $SerialNoKey = 5;
                } else {
                    $SerialNoKey = 4;
                }
                if (empty($attrnumber)) $SerialNoKey -= 1;
                if (empty($attrname)) $SerialNoKey -= 1;

                $patientformnumber = [];
                foreach ($dataOrder as $ks => $vs) {
                    //$SerialNoKey 表单序号位置
                    $dataOrderKey = $vs['sign'] . '-' . $vs['patient'] . '-' . $vs['checktime'] . '-' . $vs['stage'] . '-' . $vs['id'];

                    //一对多类型的表单 在原来 中心-受试者-表单-阶段 字符串基础上在拼接一个一对多的ID
                    if ($value['type'] == 1 || $value['group_id'] == 10 || $value['group_id'] == 11 || $value['group_id'] == 3 || $value['group_id'] == 5) $dataOrderKey .= "-" . $vs['type'];

                    //如果当前受试者已经填写过
                    if (isset($patientformnumber[$vs['patient_id']])) {
                        $patientformnumber[$vs['patient_id']] = $patientformnumber[$vs['patient_id']] + 1;
                        $data[$dataOrder_id[$dataOrderKey]][$SerialNoKey] = $patientformnumber[$vs['patient_id']];
                    } else {
                        $patientformnumber[$vs['patient_id']] = 1;
                        $data[$dataOrder_id[$dataOrderKey]][$SerialNoKey] = 1;
                    }

                    $sheetData[$ks + 2] = $data[$dataOrder_id[$dataOrderKey]];
                }
                unset($dataOrder);

            }
            $formDatas[$formname] = $sheetData;
        }

        $catalogue = $eCRF;
        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] . '盲态判读结果' . '-' . $create_time . '.xlsx';

        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header(['表单名称', '表单变量名'])->data($catalogue);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //循环指标数据生成sheet
        foreach ($formDatas as $k => $v) {
            //截取sheet名称长度
            $sheetName = mb_substr($k, 0, 16);
            if (mb_strlen($k) > 16) {
                $sheetName .= ".....";
            }
            $fileObject->addSheet($sheetName)->data($formDatas[$k]);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }

        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes : 表单锁定进度详细报告
     * @param $data
     * Author:唐伯虎不虎
     */
    public function lockinfo($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $create_time = $data['create_time'];       //创建时间
        $form = $this->getform($item_id, 0);

        $itemWhere['where'] = "is_del = 0 and id = $item_id";
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        $signDatas = [];
        foreach($itemsignatoryDatas as $k=>$v){
            $signDatas[$v['value']]['label'] = $v['label'];
            $signDatas[$v['value']]['number'] = $v['number'];
        }

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, 10);

        //不同用户的填写数据。【包括评分员和评分管理员所填数据】
        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //查询受试者表单是否锁定
        $formlockWhere['where'] = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        if(!empty($itemsig_id)) $formlockWhere['where']['itemsig_id'] = explode(',', $itemsig_id);
        if(!empty($patient_id)) $formlockWhere['where']['patient_id'] = explode(',', $patient_id);
        if(!empty($form_ids)) $formlockWhere['where']['form_ids'] = explode(',', $form_ids);
        $formlockWhere['columns'] = ['form_id','checktime_id','patient_id'];
        $lockDatas = $this->LocalService()->patientFormLock->fetchAll($formlockWhere);

        foreach($lockDatas as $lockK =>$lockV)
        {
            $lockDatas[$lockV['patient_id'].'-'.$lockV['checktime_id'].'-'.$lockV['form_id']] = 1;
            unset($lockDatas[$lockK]);
        }

        //表单 content
        $contentWhere['where'] = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        if(!empty($form_ids)) $contentWhere['where']['form_ids'] = explode(',', $form_ids);
        $contentWhere['columns'] = ['check_id','form_id'];
        $contentWhere['order'] = ['order'];
        $checkContentDatas = $this->LocalService()->itemCheckcontent->fetchAll($contentWhere);

        foreach($checkContentDatas as $formk => &$formV){
            $formV['order'] = $form[$formV['form_id']]['order'];
            $formV['check_order'] = $checktimeDatas[$formV['check_id']]['order'];
        }
        usort($checkContentDatas, function($a, $b) {
            if($a['check_order'] == $b['check_order']) {
                return $a['order'] - $b['order'];
            }
            return $a['check_order'] - $b['check_order'];
        });

        $check_formid = $this->LocalService()->itemCheckcontent->fetchCol('form_id', [
            'item_id' => $item_id,
            'is_del' => 0,
        ]);

        $countedArray = array_count_values($check_formid);

        $header_prefix = [['项目ID', '中心编号', '筛选号', '受试者姓名', '表单锁定数量']];

        if(empty($attrnumber)) unset($header_prefix[0][2]);

        if(empty($attrname)) unset($header_prefix[0][3]);

        $header_prefix[0] = array_values($header_prefix[0]);

        foreach($checkContentDatas as $key=>$value){
            if(!isset($form[$value['form_id']])) {
                unset($checkContentDatas[$key]);
                continue;
            }
            $header_prefix[0][] = $form[$value['form_id']]['name']."(".$checktimeDatas[$value['check_id']]['check_name'].")";
        }
        $dataKey = 1;
        foreach ($patientDatas as $signK => $signV)
        {
            foreach ($signV as $patientK => $patientV)
            {
                //项目ID
                $datas[$dataKey][] = $itemInfo['number'];

                //中心编号
                $datas[$dataKey][] = $signDatas[$patientV['itemsig_id']]['number'];

                if(!empty($attrnumber)) $datas[$dataKey][] = $patientV['patient_number'];

                if(!empty($attrname)) $datas[$dataKey][] = $patientV['patient_name'];

                $datas[$dataKey][] = 0;



                foreach($checkContentDatas as $infoK=>$infoV){
                    if(isset($lockDatas[$patientV['id'].'-'.$infoV['check_id'].'-'.$infoV['form_id']])){
                        $datas[$dataKey][] = '*';
                        if(!empty($attrname)){
                            $datas[$dataKey][4] += 1;
                        }else{
                            $datas[$dataKey][3] += 1;
                        }
                    }else{
                        $datas[$dataKey][] = '--';
                    }
                }
                ++$dataKey;
            }
        }

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] . '表单锁定进度详细报告' . '-' . $create_time . '.xlsx';

        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '表单锁定进度详细报告');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header($header_prefix[0])->data($datas);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes : 超窗-未查
     * @param $data
     * @throws \Exception
     * Author:唐伯虎不虎
     * Date:2024/5/13 14:50
     */
    public function hyperwindow($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $exportpatientdata_type = $data['exportpatientdata_type'];       //表单、化验单表单
        $patient_status = $data['patient_status'] ?: '10';       //受试者脱离完成状态
        $category_id = $data['category_id'] ?: '0';       //检查项分类ID
        $form_ids = $data['form_ids'] ?: '';       //检查项分类ID
        $file_ids = $data['file_ids'] ?: '';       //检查项分类ID

        $formId = '';
        if(!empty($file_ids.$form_ids)){
            $formId = explode(',',$file_ids.','.$form_ids);
        }

        $create_time = $data['create_time'];       //创建时间
        $itemWhere['where'] = "is_del = 0 and id = $item_id";
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        //配置信息
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] .'超窗-未查'. '-' . $create_time . '.xlsx';

        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '超窗数据');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        //数据
        $data = [];
        //获取项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);
        //获取项目表单
        $formDatas = $this->getform($item_id, $form_ids.','.$category_id);

        //查询受试者检查点窗口期
        $patientchecktimeWhere['where'] = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        if(!empty($patient_id))$patientchecktimeWhere['where']['patient_id'] = explode(',', $patient_id);
        if(!empty($itemsig_id))$patientchecktimeWhere['where']['itemsig_id'] = explode(',', $itemsig_id);
        $patientchecktimeWhere['columns'] = ['patient_id','checktime_id','plan_start_date','plan_end_date'];
        $patientchecktimeDatas = $this->LocalService()->itemPatientchecktime->fetchAll($patientchecktimeWhere);
        $patientchecktime_handle = [];
        foreach($patientchecktimeDatas as $v){
            $patientchecktime_handle[$v['patient_id'].'-'.$v['checktime_id']] = $v;
        }
        unset($patientchecktimeDatas);

        //查询检查点表单时间窗配置
        $item_content = $this->LocalService()->itemCheckcontent->fetchAll(['where'=>[
            'item_id' => $item_id,
            'is_del' => 0,
        ],'columns'=>['check_id','is_choose','form_id','start_time','end_time']]);

        $checkcontent = [];
        foreach($item_content as $k=>$v){
            $checkcontent[$v['check_id'].'-'.$v['form_id']] = $v;
        }
        unset($item_content);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);
        $itemsigDatas = [];
        foreach($itemsignatoryDatas as $k=>$v){
            $itemsigDatas[$v['value']] = $v;
        }

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinetdata($item_id, $itemsig_id, $patient_id, $patient_status);

        $i = 1;
        $orderData = [];

        //化验单超窗
        if($exportpatientdata_type == 2 || $exportpatientdata_type == 3){
            $checklist = array_unique(array_column($formDatas,'checklist_id'));


            $result = array_filter($checklist, function($v) {
                return $v !== '0'; // 仅过滤值为0
            });

            $categoryDatas = $this->LocalService()->dictionaryCheckcategory->fetchCol('category_name',['id'=>$result,'is_del'=>0]);

            $exceedswindowWhere = ['is_del'=>0,'item_id'=>$item_id,'data_type'=>2];
            if(!empty($patient_id))$exceedswindowWhere['patient_id'] = explode(',', $patient_id);
            if(!empty($itemsig_id))$exceedswindowWhere['itemsig_id'] = explode(',', $itemsig_id);
            if(!empty($formId))$exceedswindowWhere['form_id'] = $formId;
            $exceedswindowCheck = $this->LocalService()->projectExceedswindow->getCount($exceedswindowWhere);

            $page = ceil($exceedswindowCheck / 5000);

            $identification = $this->yieldDbDataexceedswindow($page,$exceedswindowWhere);

            foreach ($identification as $value){
                foreach($value as $v){
                    if(!isset($patientDatas[$v['patient_id']])) continue;
                    $data[$i][] = $itemInfo['number'];
                    $data[$i][] = $itemsigDatas[$patientDatas[$v['patient_id']]['itemsig_id']]['number'];
                    $data[$i][] = $patientDatas[$v['patient_id']]['patient_number'];
                    $data[$i][] = $checktimeDatas[$v['checktime_id']]['check_name'];
                    $data[$i][] = $formDatas[$v['form_id']]['name'];
                    $data[$i][] = $categoryDatas[$formDatas[$v['form_id']]['checklist_id']];
                    $data[$i][] = date('Y-m-d',$v['start_time']);
                    $data[$i][] = date('Y-m-d',$v['end_time']);
                    $data[$i][] = date('Y-m-d',$v['data_time']);
                    $data[$i][] = $v['exceedswindow_days'];
                    $data[$i][] = $v['notes'];

                    $orderData[$i]['itemsig'] = $itemsigDatas[$patientDatas[$v['patient_id']]['itemsig_id']]['order'];
                    $orderData[$i]['patient'] = $patientDatas[$v['patient_id']]['patient_order'];
                    $orderData[$i]['checktime'] = $checktimeDatas[$v['checktime_id']]['order'];
                    $orderData[$i]['key'] = $i;
                    ++$i;
                }
            }
            unset($exceedswindowCheck);
        }

        //--------------------------------------------------------------------------------------------------------------
        //表单超窗字段查询-------------------------------------------------------------------------------------------------
        //--------------------------------------------------------------------------------------------------------------
        if($exportpatientdata_type == 1 || $exportpatientdata_type == 3){
            $fieldWhere['where'] = [
                'item_id' => $item_id,
                'is_del' => 0,
                'is_hyperwindow' => 1,
            ];
            if(!empty($form_ids)) $fieldWhere['where']['form_id'] = explode(',', $form_ids);
            $fieldDatas = $this->LocalService()->itemFormField->fetchCol('name',$fieldWhere['where']);
            unset($fieldWhere);

            if(!empty($fieldDatas)) {
                $windowWhere = ['is_del'=>0,'item_id'=>$item_id,'data_type'=>1];
                if(!empty($patient_id))$windowWhere['patient_id'] = explode(',', $patient_id);
                if(!empty($itemsig_id))$windowWhere['itemsig_id'] = explode(',', $itemsig_id);
                if(!empty($formId))$windowWhere['form_id'] = $formId;
                $exceedswindowCheck = $this->LocalService()->projectExceedswindow->fetchAll([
                    'where'=>$windowWhere,
                    'columns'=>['item_id','itemsig_id','patient_id','checktime_id','form_id','field_id','exceedswindow_days','notes',
                        'start_time','end_time','data_time'
                    ]
                ]);
                if(!empty($exceedswindowCheck)){
                    foreach($exceedswindowCheck as $v){
                        if(!isset($patientDatas[$v['patient_id']])) continue;
                        $data[$i][] = $itemInfo['number'];
                        $data[$i][] = $itemsigDatas[$patientDatas[$v['patient_id']]['itemsig_id']]['number'];
                        $data[$i][] = $patientDatas[$v['patient_id']]['patient_number'];
                        $data[$i][] = $checktimeDatas[$v['checktime_id']]['check_name'];
                        $data[$i][] = $formDatas[$v['form_id']]['name'];
                        $data[$i][] = $fieldDatas[$v['field_id']];
                        $data[$i][] = date('Y-m-d',$v['start_time']);
                        $data[$i][] = date('Y-m-d',$v['end_time']);
                        $data[$i][] = date('Y-m-d',$v['data_time']);
                        $data[$i][] = $v['exceedswindow_days'];
                        $data[$i][] = $v['notes'];

                        $orderData[$i]['itemsig'] = $itemsigDatas[$patientDatas[$v['patient_id']]['itemsig_id']]['order'];
                        $orderData[$i]['patient'] = $patientDatas[$v['patient_id']]['patient_order'];
                        $orderData[$i]['checktime'] = $checktimeDatas[$v['checktime_id']]['order'];
                        $orderData[$i]['key'] = $i;
                        ++$i;
                    }
                    unset($exceedswindowCheck);
                }
            }
        }

        foreach ($orderData as $k => $v) {
            $O1[$k] = $v['itemsig'];
            $O2[$k] = $v['patient'];
            $O3[$k] = $v['checktime'];
        }

        array_multisort($O1, $O2, $O3, $orderData);

        unset($O1,$O2,$O3);

        $onesheet = [];
        foreach($orderData as $v){
            $onesheet[] = $data[$v['key']];
        }
        unset($data,$orderData);
        $fileObject->header(['项目ID','中心编号','筛选号','访视名称','表单名称','字段名称','计划时间窗开始时间','计划时间窗结束时间','实际时间','超窗天数','备注说明'])->data($onesheet);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        unset($onesheet);
//        $filePath = $fileObject->output();
        //--------------------------------------------------------------------------------------------------------------
        //未查数据处理----------------------------------------------------------------------------------------------------
        //--------------------------------------------------------------------------------------------------------------
        $twosheet = [['项目ID','中心编号','筛选号','访视名称','表单名称','字段名称','备注说明']];//表单未查数据，针对一对多数据在访视名称中需要标识出一对多数据编号
        $j = 1;
        if($exportpatientdata_type == 2 || $exportpatientdata_type == 3){
            //查询项目所有指标
            $checknameDatas = $this->LocalService()->itemCheckname->fetchCol('name',['is_del'=>0,'item_id'=>$item_id]);

            $changeWhere = new Where();
            $changeWhere->equalTo('item_id',$item_id)
                ->equalTo('is_del',1)
                ->equalTo('lock_state',1)
                ->equalTo('is_identification',1)
                ->isNotNull('collect_date');
            if(!empty($patient_id)) $changeWhere->in('patient_id',explode(',', $patient_id));
            if(!empty($category_id)) $changeWhere->in('form_id',explode(',', $category_id));
            if(!empty($itemsig_id)) $changeWhere->in('itemsig_id',explode(',', $itemsig_id));
            if(!empty($formId)) $changeWhere->in('form_id',$formId);
            $count = $this->LocalService()->itemIdentificationresultchange->getCount($changeWhere);
            $page = ceil($count / 5000);
            $identification = $this->yieldDbDataHyperWindow($page, $changeWhere,$checktimeDatas,$itemsigDatas,$patientDatas);

            foreach ($identification as $value){

                foreach($value as $v){
                    $patientid = $v['patient_id'];
                    $form_id = $v['form_id'];
                    $checktime_id = $v['checktime_id'];

                    $status = '';
                    if($checkcontent[$checktime_id.'-'.$form_id]['is_choose'] == 0){
                        $status = '【选做】';
                    }

                    if(!isset($patientDatas[$patientid])) continue;
                    $Unchecked[$j][] = $itemInfo['number'];
                    $Unchecked[$j][] = $itemsigDatas[$patientDatas[$patientid]['itemsig_id']]['number'];
                    $Unchecked[$j][] = $patientDatas[$patientid]['patient_number'];
                    $Unchecked[$j][] = $checktimeDatas[$checktime_id]['check_name'];
                    $Unchecked[$j][] = $formDatas[$form_id]['name'].$status;
                    $Unchecked[$j][] = $checknameDatas[$v['item_checkname_id']];

                    $order1Data[$j]['itemsig'] = $itemsigDatas[$patientDatas[$patientid]['itemsig_id']]['order'];
                    $order1Data[$j]['patient'] = $patientDatas[$patientid]['patient_order'];
                    $order1Data[$j]['checktime'] = $checktimeDatas[$checktime_id]['order'];
                    $order1Data[$j]['key'] = $j;
                    $j++;
                }
            }
        }

        //--------------------------------------------------------------------------------------------------------------
        //查询识别类表单--------------------------------------------------------------------------------------------------
        //--------------------------------------------------------------------------------------------------------------

        if($exportpatientdata_type == 1 || $exportpatientdata_type == 3){
            $formfieldWhere = [];
            $formWhere = [
                'is_del' => 0,
                'group_id' => [10],
                'item_id' => $item_id,
            ];
            //获取表单类型

            if(!empty($form_ids)) {
                $formWhere['id'] = explode(',', $form_ids);
                $formfieldWhere['form_id'] = explode(',', $form_ids);
            }

            $manyformId = $this->LocalService()->itemForm->fetchCol('id',$formWhere);

            if(empty($form_ids)){
                $formfieldWhere['form_id'] = $manyformId;
            }
            //获取当前项目下所有字段
            $formfieldDatas = $this->LocalService()->itemFormField->fetchCol('name',$formfieldWhere);

            $formfieldtypeDatas = $this->LocalService()->itemFormField->fetchCol('type',$formfieldWhere);

        }

        if(!empty($manyformId)){
            $many = [];

            //处理表单未is_yc化验单类表单 开具医嘱/化验单状态 1:已开具 0:不检查 -1:未填写
            //获取未完成的表单
            $formContentWhere = new Where();
            $formContentWhere->equalTo('is_del',0)
                ->equalTo('is_inactive',0)
                ->in('form_id',$manyformId)
                ->equalTo('item_id',$item_id);

            if ($patient_id != 0) $formContentWhere->in('patient_id',StringHelper::toArray($patient_id));
            if ($form_ids != 0) $formContentWhere->in('form_id',StringHelper::toArray($form_ids));
            if ($itemsig_id != 0) $formContentWhere->in('itemsig_id',StringHelper::toArray($itemsig_id));
            $formContentWhere
                ->nest()
                ->equalTo('is_complete',0)
                ->or
                ->nest()
                ->equalTo('is_complete',1)
                ->equalTo('is_yc',0)
                ->unnest()
                ->unnest();

            $count = $this->LocalService()->patientFormContent->getCount($formContentWhere);
            $page = ceil($count / 5000);

            $yieldPatientFormDatas = $this->yieldDbPatientForm($page, $formContentWhere,$checktimeDatas,$itemsigDatas,$patientDatas);
            $rules = [];
            foreach($yieldPatientFormDatas as $key => $value){

                foreach($value as $dataV){

                    if(isset($rules[$dataV['form_id']])){
                        $rule_handles = $rules[$dataV['form_id']];
                    }else{
                        $rules[$dataV['form_id']] = $rule_handles = $this->LocalService()->itemForm->getPreviewConfig($dataV['form_id'],true);
                    }

                    //计划外检查点跳过
                    if(!empty($checktimeDatas[$dataV['checktime_id']]['patientchecktime_id'])) continue;

                    $contentData = json_decode($dataV['data'],true);

                    foreach($rule_handles['generateFields'] as $configK=>$configV){

                        if(
                            (isset($contentData[$configV]) && empty($contentData[$configV]))
                            ||
                            ($formfieldtypeDatas[$configV] == 2 && $contentData[$configV] == '--')
                            ||
                            ($formfieldDatas[$configV] == '备注说明' && $dataV['is_yc'] == 0))
                        {
                            $status = '';
                            if(isset($checkcontent[$dataV['checktime_id'].'-'.$dataV['form_id']]) &&$checkcontent[$dataV['checktime_id'].'-'.$dataV['form_id']]['is_choose'] == 0){
                                $status = '【选做】';
                            }
                            $position = '';
                            if($formDatas[$dataV['form_id']]['type'] == 1){
                                $search_value = $dataV['patient_id'].'-'.$dataV['form_id'];
                                if($formDatas[$dataV['form_id']]['group_id'] !=4){
                                    $search_value .= '-'.$dataV['checktime_id'];
                                }

                                if(isset($many[$search_value])){
                                    $index = $many[$search_value] += 1;
                                }else{
                                    $index = $many[$search_value] = 1;
                                }

                                $position .= '-【' . ($index + 1) .'】';
                            }
                            if(!isset($patientDatas[$dataV['patient_id']])) continue;

                            $Unchecked[$j][] = $itemInfo['number'];
                            $Unchecked[$j][] = $itemsigDatas[$patientDatas[$dataV['patient_id']]['itemsig_id']]['number'];
                            $Unchecked[$j][] = $patientDatas[$dataV['patient_id']]['patient_number'];
                            $Unchecked[$j][] = $checktimeDatas[$dataV['checktime_id']]['check_name']??'';
                            $Unchecked[$j][] = $formDatas[$dataV['form_id']]['name'].$status.$position;

//                            if (strpos($configV, '-') !== false) {
//                                $parts = explode('-', $configV);
//                                if (count($parts) >= 2) {
//                                    $configV = $parts[count($parts) - 2];
//                                }
//                            }
//                            $Unchecked[$j][] = $formfieldDatas[$configV];

                            $order1Data[$j]['itemsig'] = $itemsigDatas[$patientDatas[$dataV['patient_id']]['itemsig_id']]['order'];
                            $order1Data[$j]['patient'] = $patientDatas[$dataV['patient_id']]['patient_order'];
                            $order1Data[$j]['checktime'] = $checktimeDatas[$dataV['checktime_id']]['order'] ?? '0';
                            $order1Data[$j]['key'] = $j;

                            $prev_field = '';
                            if (strpos($configV, '-') !== false) {
                                $fieldArr = explode("-", $configV);
                                $configV = $fieldArr[0];

                                $prev_field = '('.$formfieldDatas[$fieldArr[1]].')';
                            }

                            $Unchecked[$j][] = $formfieldDatas[$configV].$prev_field;


                            if($dataV['is_yc'] == 0 && !empty($contentData[$configV])){
                                $Unchecked[$j][] = '【'.$contentData[$configV].'】';
                            }

                            $j++;
                        }
                    }
                }
            }

            unset($formfieldDatas,$formfieldtypeDatas);

        }


        foreach ($order1Data as $k => $v) {
            $J1[$k] = $v['itemsig'];
            $J2[$k] = $v['patient'];
            $J3[$k] = $v['checktime'];
        }

        array_multisort($J1, $J2, $J3, $order1Data);

        unset($J1,$J2,$J3);

        foreach($order1Data as $v){
            $twosheet[] = $Unchecked[$v['key']];
        }
        $fileObject->addSheet('未查数据')->data($twosheet);

        unset($twosheet,$order1Data);

        $fileObject->output();
    }

    public function yieldDbDataHyperWindow($page, $syslogWhere,$checktimeDatas,$itemsigDatas,$patientDatas){
        $limit = 5000;
        for($i = 1; $i <= $page; $i++){
            $offset = ($i - 1) * $limit + 1;
            $resultChangeWhere['where'] = $syslogWhere;
            $resultChangeWhere['limit'] = $limit;
            $resultChangeWhere['offset'] = $offset;
            $resultChangeWhere['order'] = ['itemsig_id'];
            $resultChangeWhere['columns'] = ['patient_id','checktime_id','collect_date','item_name','form_id','category_id','item_checkname_id'];
            yield  $this->LocalService()->itemIdentificationresultchange->fetchAll($resultChangeWhere);

        }
    }

    public function yieldDbDataexceedswindow($page, $syslogWhere){
        $limit = 5000;
        for($i = 1; $i <= $page; $i++){
            $offset = ($i - 1) * $limit + 1;
            $resultChangeWhere['where'] = $syslogWhere;
            $resultChangeWhere['limit'] = $limit;
            $resultChangeWhere['offset'] = $offset;
            $resultChangeWhere['order'] = ['itemsig_id'];
            $resultChangeWhere['columns'] = ['item_id','itemsig_id','patient_id','checktime_id','form_id','exceedswindow_days','notes',
                'start_time','end_time','data_time'
            ];
            yield $this->LocalService()->projectExceedswindow->fetchAll($resultChangeWhere);
        }
    }


    public function yieldDbPatientForm($page, $formContentWhere,$checktimeDatas,$itemsigDatas,$patientDatas)
    {
        $limit = 5000;
        for($i = 1; $i <= $page; $i++){
            $offset = ($i - 1) * $limit + 1;
            $patientFormContentWhere['limit'] = $limit;
            $patientFormContentWhere['offset'] = $offset;
            $patientFormContentWhere['where'] = $formContentWhere;
            $patientFormContentWhere['columns'] = ['id', 'patient_id', 'form_id', 'checktime_id', 'data', 'itemsig_id', 'is_yc', 'create_user_id','is_complete'];
            yield $this->LocalService()->patientFormContent->fetchAll($patientFormContentWhere);
        }

    }


    /**
     * Notes : 获取在施项目合作方
     * @param $data
     * Author:唐伯虎不虎
     */
    public function only($data)
    {
        //查询所有在施项目
        $itemwhere['where'] = [
            'is_del' => 0,
            'status' => 0,
            'is_mainitem' => 1,
        ];
        $itemwhere['columns'] = ['id','name','number'];
        $iteminfos = $this->LocalService()->itemInfo->fetchAll($itemwhere);
        $itemStrs = array_column($iteminfos,'id');

        $signastrs = $this->LocalService()->itemSignatory->fetchCol('signatory_id',[
            'is_del' => 0,
            'item_id' => $itemStrs,
        ]);
        $signastrs = array_unique($signastrs);

        $create_time = $data['create_time'];
        $signainfoWhere['where'] = [
            'is_del' => 0,
            'id' => $signastrs,
        ];
        $signainfoWhere['columns'] = ['info_name','province_city'];
        $signDatas = $this->LocalService()->signatoryInfo->fetchAll($signainfoWhere);

        $itemWhere['where'] = "is_del = 0 and id = ".$data['item_id'];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] .'超窗-未查'. '-' . $create_time . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '中心信息');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $data = [];

        foreach($signDatas as $k=>$v){
            $data[$k+1][] = $v['info_name'];
            $data[$k+1][] = $v['province_city'];
        }
        $fileObject->header(['中心名称','所在城市'])->data($data);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        $data2 = [['项目名称']];

        foreach($iteminfos as $k=>$v){
            $data2[$k+1][] = '';
            $data2[$k+1][] = $v['name'];
        }

        $fileObject->addSheet('项目名称')->data($data2);

        $filePath = $fileObject->output();

    }

    /**
     * Notes : 表单锁定进度详细报告
     * @param $data
     * Author:唐伯虎不虎
     */
    public function confirm($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $create_time = $data['create_time'];       //创建时间
        $form = $this->getform($item_id, 0);

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);
        $signDatas = [];
        foreach($itemsignatoryDatas as $k=>$v){
            $signDatas[$v['value']]['label'] = $v['label'];
            $signDatas[$v['value']]['number'] = $v['number'];
        }

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, 10);

        //不同用户的填写数据。【包括评分员和评分管理员所填数据】
        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //查询受试者SDV、Review、EDC锁定、电子签名
        $confirmData = $reviewData = $lockData = $SignatureData = $formGroupArr = [];
        $patientWorkbatchWhere = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($patient_id)) {
            $patientWorkbatchWhere['patient_id'] = explode(',', $patient_id);
        }
        $patientWorkbatchDatas = $this->LocalService()->projectPatientworkbatch->fetchAll([
            'where'=>$patientWorkbatchWhere,
            'columns'=>['patient_id','checktime_id','form_id','formgroup_id','is_sdv','is_review','edc_lock','is_signature']
        ]);
        unset($patientWorkbatchWhere);
        if(!empty($patientWorkbatchDatas)){
            foreach($patientWorkbatchDatas as $patientWorkbatchKey=>$patientWorkbatchData){
                $batch_data_key = $patientWorkbatchData['patient_id'].'-'.$patientWorkbatchData['checktime_id'].'-'.$patientWorkbatchData['form_id'];
                //SDV操作
                if($patientWorkbatchData['is_sdv'] == 1){
                    $confirmData[$batch_data_key] = 1;
                }
                //Review操作
                if($patientWorkbatchData['is_review'] == 1){
                    $reviewData[$batch_data_key] = 1;
                }
                //EDC锁定操作
                if($patientWorkbatchData['edc_lock'] == 1){
                    $lockData[$batch_data_key] = 1;
                }
                //电子签名操作
                if($patientWorkbatchData['is_signature'] == 1){
                    $SignatureData[$batch_data_key] = 1;
                }
                $formGroupArr[$patientWorkbatchData['form_id']] = $patientWorkbatchData['formgroup_id'];
                unset($batch_data_key);
                unset($patientWorkbatchDatas[$patientWorkbatchKey]);
            }
        }
        unset($patientWorkbatchDatas);

        //*********************************检查点及受试者检查点信息查询*********************************

        $patientchecktimeWhere = [
            'item_id' => $item_id,
            'is_del' => 0,

        ];
        if(!empty($itemsig_id)) $patientchecktimeWhere['itemsig_id'] = explode(',', $itemsig_id);
        if(!empty($patient_ids)) $patientchecktimeWhere['patient_id'] = explode(',', $patient_ids);
        $patientchecktimeData = $this->LocalService()->itemPatientchecktime->fetchAll([
            'where'=>ArrayUtils::merge([
                'is_now_state' => 1,
            ], $patientchecktimeWhere),
            'columns'=>['id','patient_id','check_order','checktime_id']
        ]);

        $patientchecktimeDatas = ArrayHelper::index($patientchecktimeData,'patient_id');


        $patientLeave = $this->LocalService()->itemPatientchecktime->fetchAll([
            'where'=> ArrayUtils::merge([
                new Operator('leave_type', Operator::OP_NE, '')
            ], $patientchecktimeWhere),
            'columns'=>['id','patient_id','check_order','checktime_id']
        ]);

        $patientLeaveDatas = ArrayHelper::index($patientLeave,'patient_id');

        $patientchecktimeDatas = array_replace($patientchecktimeDatas,$patientLeaveDatas);

        //*********************************检查点及受试者检查点信息查询*********************************


        //表单 content
        $contentWhere['where'] = [
            'item_id' => $item_id,
            'is_del' => 0,
        ];
        if(!empty($form_ids)) $contentWhere['where']['form_ids'] = explode(',', $form_ids);
        $contentWhere['columns'] = ['check_id','form_id'];
        $contentWhere['order'] = ['order'];
        $checkContentDatas = $this->LocalService()->itemCheckcontent->fetchAll($contentWhere);

        foreach($checkContentDatas as $formk => &$formV){
            $formV['order'] = $form[$formV['form_id']]['order'];
            $formV['check_order'] = $checktimeDatas[$formV['check_id']]['order'];
        }
        usort($checkContentDatas, function($a, $b) {
            if($a['check_order'] == $b['check_order']) {
                return $a['order'] - $b['order'];
            }
            return $a['check_order'] - $b['check_order'];
        });



        $header_prefix = [['项目ID', '中心编号', '筛选号', '受试者姓名', '表单完成数量']];

        if(empty($attrnumber)) unset($header_prefix[0][2]);

        if(empty($attrname)) unset($header_prefix[0][3]);

        $header_prefix[0] = array_values($header_prefix[0]);

        foreach($checkContentDatas as $key=>$value){
            if(!isset($form[$value['form_id']])) {
                unset($checkContentDatas[$key]);
                continue;
            }
            $header_prefix[0][] = $form[$value['form_id']]['name']."(".$checktimeDatas[$value['check_id']]['check_name'].")";
        }

        $path = APP_PATH . '/data/exportFile';

        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] . 'SDV情况' . '-' . $create_time . '.xlsx';

        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '表单SDV进度详情报告');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $typeData = [0=>$confirmData, 1=>$reviewData,2=>$lockData,3=>$SignatureData];
        $sheetNameArray = [1=>'表单Review进度详细报告',2=>'表单锁定进度详细报告',3=>'表单签名进度详细报告'];
        foreach($typeData as $key=>$value)
        {
            $datas = [];
            if($key > 0){
                $datas[0] = $header_prefix[0];
            }
            $dataKey = 1;
            foreach ($patientDatas as $signK => $signV)
            {
                foreach ($signV as $patientK => $patientV)
                {
                    //项目ID
                    $datas[$dataKey][] = $itemInfo['number'];

                    //中心编号
                    $datas[$dataKey][] = $signDatas[$patientV['itemsig_id']]['number'];

                    if(!empty($attrnumber)) $datas[$dataKey][] = $patientV['patient_number'];

                    if(!empty($attrname)) $datas[$dataKey][] = $patientV['patient_name'];

                    $datas[$dataKey][] = 0;

                    foreach($checkContentDatas as $infoK=>$infoV){
                        if($checktimeDatas[$infoV['check_id']]['check_order'] > $patientchecktimeDatas[$patientV['id']]['check_order']){

                            $datas[$dataKey][] = '';
                            continue;
                        }elseif($checktimeDatas[$infoV['check_id']]['check_order'] == $patientchecktimeDatas[$patientV['id']]['check_order']){
                            if($checktimeDatas[$infoV['check_id']]['id'] > $patientchecktimeDatas[$patientV['id']]['checktime_id']){
                                $datas[$dataKey][] = '';
                                continue;
                            }
                        }

                        $edc_operate = 0;//判断此操作EDC是否已执行
                        if(isset($formGroupArr[$infoV['form_id']])){
                            $value_key = $patientV['id'].'-'.$infoV['check_id'].'-'.$infoV['form_id'];
                            //贯穿全程
                            if($formGroupArr[$infoV['form_id']] == FormGroup::THROUGH_PROCESS){
                                $value_key = $patientV['id'].'-0-'.$infoV['form_id'];
                            }
                            //AE类
                            if($formGroupArr[$infoV['form_id']] == FormGroup::AE){
                                $value_key = $patientV['id'].'--1-'.$infoV['form_id'];
                            }
                            //AE类
                            if($formGroupArr[$infoV['form_id']] == FormGroup::SAE){
                                $value_key = $patientV['id'].'--2-'.$infoV['form_id'];
                            }
                            if(isset($value[$value_key]) && !empty($value[$value_key])){
                                $edc_operate = 1;
                            }
                        }
                        if($edc_operate == 1){
                            $datas[$dataKey][] = '*';
                            if(!empty($attrname)){
                                $datas[$dataKey][4] += 1;
                            }else{
                                $datas[$dataKey][3] += 1;
                            }
                        }else{
                            $datas[$dataKey][] = '--';
                        }
                        unset($edc_operate);
                    }
                    ++$dataKey;
                }
            }

            if($key == 0){
                $fileObject->header($header_prefix[0])->data($datas);
                $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
            }else{
                $fileObject->addSheet($sheetNameArray[$key])->data($datas);
                $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
            }

        }

        //输出数据
        $filePath = $fileObject->output();
    }

    /**
     * Notes :
     * @throws \Exception
     * Author:唐伯虎不虎
     * Date:2022/9/15 10:54
     */
    public function execute($data)
    {
        //1、 受试者数据  2、受试者进度详细报告 3、表单变量 4、化验单变量 5、受试者失访报告 6、随机号明细
        switch($data['export_type']){
            case 1:
//                $this->tmp();
                $this->formdata($data);
                break;
            case 2:
                $this->patientformreport($data);
                break;
            case 3:
                $this->formVariable($data);
                break;
            case 4:
                $this->csVariable($data);
                break;
            case 5:
                $this->exportbooked($data);
                break;
            case 6:
                $this->randomData($data);
                break;
            case 7:
                $this->logData($data);
                break;
            case 8:
                $this->downformfileocrcsae($data);
                break;
            case 9:
                $this->researchcenter($data);
                break;
            case 10:
                $this->excelmodel($data);
                break;
            case 11:
                $this->score($data);
                break;
            case 12:
                $this->lockinfo($data);
                break;
            case 13:
                $this->patientformreport_d($data);
                break;
            case 14:
                $this->hyperwindow($data);
                break;
            case 15:
                //$this->itemdatareport($data);
                $this->newitemdatareport($data);
            case 16:
                $this->telformdata($data);
                //break;
//            case 14:
//                $this->only($data);
//                break;
//            case 14:
//                $this->defaultoptions($data);
//                break;
            case 17:
                $this->formlogData($data);
                break;
            case 18:
                $this->logerrorData($data);
                break;
            case 19:
                $this->doctoradvice($data);
                break;
            case 20:
                $this->confirm($data);
                break;
            case 21:
                $this->itemevent($data);
                break;
        }
        return true;
    }

    /**
     * Notes:项目数据管理阶段报告导出(Word)
     * User: lltyy
     * DateTime: 2024/5/13 11:21
     *
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public function itemdatareport($send_data)
    {
        $send_data['create_time'] = isset($send_data['create_time']) && !empty($send_data['create_time']) ? $send_data['create_time'] : date('YmdHis',time());
        $item_id = isset($send_data['item_id']) && !empty($send_data['item_id']) ? $send_data['item_id'] : 0;
        $itemsig_id = isset($send_data['itemsig_ids']) && !empty($send_data['itemsig_ids']) ? $send_data['itemsig_ids'] : '';
        $patient_status = isset($send_data['patient_status']) && !empty($send_data['patient_status']) ? $send_data['patient_status'] : '10';
        $patient_ids = isset($send_data['patient_ids']) && !empty($send_data['patient_ids']) ? $send_data['patient_ids'] : '';

        if (empty($item_id)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');


        //查询项目详情
        $iteminfo = $this->LocalService()->itemInfo->fetchOne(['where'=> [
            'is_del' => 0,
            'id' => $item_id,
        ],'columns'=>['id', 'name','var_name','plan_joingroup']]);

        $itemName = $iteminfo['name'];

        //获取入组受试者
        $patientDatas = $this->LocalService()->patient->getItemGroupPatient($item_id, $itemsig_id, $patient_ids, $patient_status);
        $sigPatientDatas = $patientDatas['sig'];
        $monthPatientDatas = $patientDatas['month'];
        unset($patientDatas);

        //获取项目中心
        $signDatas = $sigGroupList = $sigBarLabelList = $sigBarValueList = [];
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);
        $all_sig_group_count = 0;
        if(!empty($itemsignatoryDatas)){
            foreach ($itemsignatoryDatas as $itemsignatoryKey => $itemsignatoryData) {
                $itemsignatoryData_id = $itemsignatoryData['value'];
                $sig_group_patient = isset($sigPatientDatas[$itemsignatoryData_id]) && !empty($sigPatientDatas[$itemsignatoryData_id]) ? count(array_values($sigPatientDatas[$itemsignatoryData_id])) : 0;
                $sig_plangroup_patient = !empty($itemsignatoryData['plan_joingroup']) ? $itemsignatoryData['plan_joingroup'] : 0;
                $sig_group_ratio = !empty($sig_group_patient) && !empty($sig_plangroup_patient) ? floor(($sig_group_patient/$sig_plangroup_patient)*100) : '';
                $signDatas[$itemsignatoryData['value']] = $itemsignatoryData['number'];
                if(!empty($sig_group_patient)){
                    $sig_plangroup_patient_show = !empty($sig_plangroup_patient) ? $sig_plangroup_patient : '';
                    $sig_group_patient_show = !empty($sig_group_patient) ? $sig_group_patient : '';
                    $sig_group_ratio_show = !empty($sig_group_ratio) ? $sig_group_ratio.'%' : '';
                    $sigGroupList[] = [$itemsignatoryData['number'],$itemsignatoryData['label'],$sig_plangroup_patient_show,$sig_group_patient_show,$sig_group_ratio_show];
                    $sigBarLabelList[] = $itemsignatoryData['label'];
                    $sigBarValueList[] = $sig_group_patient;
                    unset($sig_plangroup_patient_show);
                    unset($sig_group_patient_show);
                    unset($sig_group_ratio_show);
                }
                $all_sig_group_count += $sig_group_patient;
                unset($itemsignatoryData_id);
                unset($sig_group_patient);
                unset($sig_plangroup_patient);
                unset($sig_group_ratio);
                unset($itemsignatoryDatas[$itemsignatoryKey]);
            }
        }
        unset($itemsignatoryDatas);
        $item_group = !empty($iteminfo['plan_joingroup']) ? $iteminfo['plan_joingroup'] : '';
        $all_sig_group_count_show = !empty($all_sig_group_count) ? $all_sig_group_count : '';;
        $sigGroupList[] = ['','总计',$item_group,$all_sig_group_count_show,''];
        unset($all_sig_group_count_show);

        //查询项目检查点
        $checktimeDatas = $this->LocalService()->itemChecktime->fetchAll(['where'=> [
            'is_del' => 0,
            'item_id' => $item_id,
        ],'columns'=>['id', 'check_name', 'stage_id', 'random_id'],'order'=>['check_order']]);

        //查询项目表单
        $form = $checkForm = [];
        $formDatas = $this->LocalService()->itemForm->fetchAll(['where'=> [
            'is_del' => 0,
            'item_id' => $item_id,
        ],'columns'=>['id', 'group_id'],'order'=>['order']]);
        if(!empty($formDatas)) {
            foreach ($formDatas as $formKey => $formV) {
                $form[] = $formV['id'];
                if($formV['group_id'] == FormGroup::CHECK_OCR){
                    $checkForm[] = $formV['id'];
                }
                unset($formDatas[$formKey]);
            }
        }
        unset($formDatas);

        //查询当前检查点以及表单
        $checkcontentDatas = [];
        $checkcontent = $this->LocalService()->itemCheckcontent->fetchAll(['where'=> [
            'is_del' => 0,
            'item_id' => $item_id,
        ],'columns'=>['id', 'form_id', 'check_id'],'order'=>['order']]);
        if(!empty($checkcontent)) {
            foreach ($checkcontent as $checkcontentKey => $checkcontent_v) {
                $checkcontentDatas[$checkcontent_v['check_id']][] = $checkcontent_v;
                unset($checkcontent[$checkcontentKey]);
            }
        }
        unset($checkcontent);


        //查询受试者表单、化验单是否完成 patienrform
        $patientform = [];
        $patientformDatas = $this->LocalService()->patientForm->fetchAll(['where'=> [
            'is_del' => 0,
            'is_complete' => 1,
            'item_id' => $item_id,
        ],'columns'=>['id', 'patient_id', 'checktime_id', 'form_id', 'is_complete']]);
        if(!empty($patientformDatas)) {
            foreach ($patientformDatas as $patientformKey => $patientformData) {
                $patientform_key = $patientformData['patient_id'] . '-' . $patientformData['checktime_id'] . '-' . $patientformData['form_id'];
                $patientform[$patientform_key] = $patientformData['is_complete'];
                unset($patientform_key);
                unset($patientformDatas[$patientformKey]);
            }
        }
        unset($patientformDatas);

        //查询受试者表单、化验单是否完成 patienrformcontent
        $patientformcontent = [];
        $patientFormContentWhere = [
            'is_del' => 0,
            'item_id' => $item_id,
            new Operator('is_yc', Operator::OP_NE, 0),
        ];
        if(!empty($checkForm)){
            $patientFormContentWhere['form_id'] = $checkForm;
            $patientFormCOntentWhere[] = new Operator('is_yc', Operator::OP_NE, -1);
        }
        unset($checkForm);
        $patientformcontentDatas = $this->LocalService()->patientFormContent->fetchAll(['where'=>$patientFormContentWhere,'columns'=>['id', 'patient_id', 'checktime_id', 'form_id']]);
        unset($patientFormContentWhere);
        if(!empty($patientformcontentDatas)){
            foreach ($patientformcontentDatas as $patientformcontentKey => $patientformcontentData) {
                $patientformcontent_key = $patientformcontentData['patient_id'].'-'.$patientformcontentData['checktime_id'].'-'.$patientformcontentData['form_id'];
                $patientformcontent[$patientformcontent_key] = $patientformcontentData;
                unset($patientformcontent_key);
                unset($patientformcontentDatas[$patientformcontentKey]);
            }
        }
        unset($patientformcontentDatas);


        //随机方案
        $randomData = $this->LocalService()->itemRandom->fetchAll(['where'=> [
            'is_del' => 0,
            'item_id' => $item_id,
        ],'columns'=>['id', 'random_name', 'type']]);
        $randomDatas = [];
        foreach ($randomData as $randomKey => $random_v) {
            $randomDatas[$random_v['id']] = $random_v;
            unset($randomData[$randomKey]);
        }
        unset($randomData);


        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->addFontStyle('cStyle',array('name' => '宋体','size'=>11));//内容样式
        $phpWord->addFontStyle('bStyle',array('name' => '宋体','size'=>13,'bold'=>true));//加粗样式
        $phpWord->addFontStyle('titleStyle',array('name' => '宋体','size'=>16,'bold'=>true));//标题样式
        $phpWord->addFontStyle('tableTitleStyle',array('name' => '宋体','size'=>14,'bold'=>true));//表格标题样式
        //表格样式
        $styleTable = array('borderSize'=>6,'alignment'=>'center','cellMargin'=>80);
        $phpWord->addTableStyle('myOwnTableStyle',$styleTable);
        unset($styleTable);

        $section = $phpWord->addSection([
            'orientation'=>\PhpOffice\PhpWord\Style\Section::ORIENTATION_LANDSCAPE //横向
        ]);//创建新页面

        //标题
        $section->addText('('.$itemName.')项目数据管理阶段报告','titleStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行

        //内容
        $item_group_show = !empty($item_group) ? $item_group : '';
        $section->addText('方案入组例数：'.$item_group_show,'bStyle',['alignment'=>'left']);
        $section->addTextBreak(1);//换行
        unset($item_group);
        unset($item_group_show);

        //入组例数列表 表格
        $section->addText('入组例数列表','tableTitleStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行
        $sigGroupTable = $section->addTable('myOwnTableStyle');//添加表格
        $sigGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
        //添加表头(数字代表宽度)
        $sigGroupTable->addCell(2000,['bgColor'=>'d0d0d0'])->addText('中心号','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(5000,['bgColor'=>'d0d0d0'])->addText('中心名称','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('计划入组例数','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('入组例数','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('入组完成比例','bStyle',['alignment'=>'center']);
        //添加内容
        if(!empty($sigGroupList)){
            foreach($sigGroupList as $sigGroupKey=>$sigGroupData){
                $sigGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                //添加表头(数字代表宽度)
                $sigGroupTable->addCell(2000)->addText($sigGroupData[0],'cStyle',['alignment'=>'center']);
                $sigGroupTable->addCell(5000)->addText($sigGroupData[1],'cStyle',['alignment'=>'center']);
                $sigGroupTable->addCell(3000)->addText($sigGroupData[2],'cStyle',['alignment'=>'center']);
                $sigGroupTable->addCell(3000)->addText($sigGroupData[3],'cStyle',['alignment'=>'center']);
                $sigGroupTable->addCell(3000)->addText($sigGroupData[4],'cStyle',['alignment'=>'center']);
                unset($sigGroupList[$sigGroupKey]);
            }
        }
        unset($sigGroupList);
        $section->addTable($sigGroupTable);
        $section->addTextBreak(1);//换行
        unset($sigGroupTable);

        //入组例数列表 柱状图
        if(!empty($sigBarLabelList)){
            $sigChart = $section->addChart('bar', $sigBarLabelList, $sigBarValueList, [
                'width' => '6000000',
                'height' => '3000000',
                'showAxisLabels' => true,
                'dataLabelOptions' => [
                    'showVal' => false,
                    'showCatName' => false
                ]
            ]);
            $sigChart->getStyle()->setShowGridY();
            $section->addTextBreak(1);//换行
            unset($sigChart);
        }
        unset($sigBarLabelList);
        unset($sigBarValueList);



        //项目入组总进度 表格
        $monthBarLableList = $monthBarValueList = [];
        $section->addText('项目入组总进度','tableTitleStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行
        $monthGroupTable = $section->addTable('myOwnTableStyle');//添加表格
        $monthGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
        //添加表头(数字代表宽度)
        $monthGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('月份','bStyle',['alignment'=>'center']);
        $monthGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('当月入组例数合计','bStyle',['alignment'=>'center']);
        $monthGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('总计入组','bStyle',['alignment'=>'center']);
        if(!empty($monthPatientDatas)){
            $preCount = 0;
            ksort($monthPatientDatas);
            foreach($monthPatientDatas as $monthKey=>$monthData){
                $monthDataCount = count($monthData);
                $monthBarLableList[] = $monthKey;
                $monthBarValueList[] = $monthDataCount;
                $preCount += $monthDataCount;
                $monthDataCountShow = !empty($monthDataCount) ? $monthDataCount : '';
                $preCountShow = !empty($preCount) ? $preCount : '';
                $monthGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                //添加表头(数字代表宽度)
                $monthGroupTable->addCell(3000)->addText($monthKey,'cStyle',['alignment'=>'center']);
                $monthGroupTable->addCell(3000)->addText($monthDataCountShow,'cStyle',['alignment'=>'center']);
                $monthGroupTable->addCell(3000)->addText($preCountShow,'cStyle',['alignment'=>'center']);
                unset($monthDataCount);
                unset($preCountShow);
                unset($monthDataCountShow);
                unset($monthPatientDatas[$monthKey]);
            }
            unset($preCount);
        }
        unset($monthPatientDatas);
        $section->addTable($monthGroupTable);
        $section->addTextBreak(1);//换行
        unset($monthGroupTable);

        //项目入组总进度 柱状图
        if(!empty($monthBarLableList)) {
            $monthChart = $section->addChart('column', $monthBarLableList, $monthBarValueList, [
                'width' => '6000000',
                'height' => '3000000',
                'showAxisLabels' => true,
                'dataLabelOptions' => [
                    'showVal' => false,
                    'showCatName' => false
                ]
            ]);
            $monthChart->getStyle()->setShowGridY();
            $section->addTextBreak(1);//换行

            unset($monthChart);
        }
        unset($monthBarLableList);
        unset($monthBarValueList);



        //数据录入进度
        $section->addText('2、数据录入进度','bStyle',['alignment'=>'left']);
        $section->addTextBreak(1);//换行
        $section->addText('表格中数字表示该访视期对应受试者完成的工作事项，未产生任何数据的已做标红处理。','cStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行

        $summary = [];
        if(!empty($checktimeDatas)){
            foreach ($checktimeDatas as $checktimeK => $checktimeV) {
                $kk = 0;
                //循环受试者 查询受试者表单填写状态
                foreach ($signDatas as $signk => $signv) {
                    foreach ($sigPatientDatas[$signk] as $key => $sigPatientV) {
                        if (!isset($summary[$sigPatientV['id']][$checktimeV['id']])) {
                            $summary[$sigPatientV['id']][$checktimeV['id']] = 0;
                        }
                        $kk++;
                        //随机分组
                        if ($randomDatas[$checktimeV['random_id']]['type'] == 2) {
                            if ($sigPatientV['random_id'] != $checktimeV['random_id']) continue;
                        }
                        //已完成表单数量
                        foreach ($checkcontentDatas[$checktimeV['id']] as $kd => $vd) {
                            if (!in_array($vd['form_id'],$form)) continue;
                            $patientformcomplete = isset($patientform[$sigPatientV['id'] . '-' . $checktimeV['id'] . '-' . $vd['form_id']]['is_complete']) ? $patientform[$sigPatientV['id'] . '-' . $checktimeV['id'] . '-' . $vd['form_id']] : '9';
                            if ($patientformcomplete == 1) {
                               $summary[$sigPatientV['id']][$checktimeV['id']] += 1;
                            } elseif ($patientformcomplete == 9) {
                                continue;
                            }
                            unset($patientformcomplete);
                        }
                    }
                }
                unset($kk);
            }
        }
        unset($patientform);
        unset($patientformcontent);

        $gather = [];
        if(!empty($randomDatas)){
            //获取患者隐私信息
            $hidePatientAttr = $this->LocalService()->patientattrs->fetchCol('attr_field',[
                'is_del' => 0,
                'item_id' => $item_id,
                'is_hide' => 1,
            ]);
            $hidePatientAttr = array_values($hidePatientAttr);
            foreach ($randomDatas as $randomK => $randomV) {
                $headerdata = [];
                $headerarr = ['中心编号'];
                if(!in_array('number',$hidePatientAttr)){
                    $headerarr[] = '受试者筛选号';
                }
                if(!in_array('name',$hidePatientAttr)){
                    $headerarr[] = '受试者姓名';
                }
                foreach ($checktimeDatas as $key => $value) {
                    if ($value['random_id'] != $randomV['id']) continue;
                    $headerarr[] = $value['check_name'];
                }
                $headerdata[] = $headerarr;
                $kk = 0;
                $headerdata[$kk + 1][] = '应填表单数量';
                if(!in_array('number',$hidePatientAttr)){
                    $headerdata[$kk + 1][] = '';
                }
                if(!in_array('name',$hidePatientAttr)){
                    $headerdata[$kk + 1][] = '';
                }
                foreach ($checktimeDatas as $kc => $vc) {
                    if ($vc['random_id'] != $randomV['id']) continue;
                    foreach ($checkcontentDatas[$vc['id']] as $kd => $vd) {
                        if (!in_array($vd['form_id'],$form)) {
                            unset($checkcontentDatas[$vc['id']][$kd]);
                        }
                    }
                    $headerdata[$kk + 1][] = count($checkcontentDatas[$vc['id']]);
                }
                foreach ($signDatas as $signk => $signv) {
                    foreach ($sigPatientDatas[$signk] as $key => $vv) {
                        if ($vv['random_id'] == '' || $vv['random_id'] == NULL) $vv['random_id'] = 0;
                        //随机分组
                        if ($randomDatas[$randomV['id']]['type'] == 2) {
                            if ($vv['random_id'] != $randomV['id']) continue;
                        }
                        $kk++;
                        $headerdata[$kk + 1][] = $signv;
                        if(!in_array('number',$hidePatientAttr)){
                            $headerdata[$kk + 1][] = $vv['patient_number'];
                        }
                        if(!in_array('name',$hidePatientAttr)){
                            $headerdata[$kk + 1][] = $vv['patient_name'];
                        }
                        foreach ($checktimeDatas as $kc => $vc) {
                            if ($vc['random_id'] != $randomV['id']) continue;
                            $headerdata[$kk + 1][] = $summary[$vv['id']][$vc['id']];
                        }
                    }
                }
                $gather[$randomV['id']] = $headerdata;

                unset($kk);
                unset($headerdata);
            }
            unset($hidePatientAttr);
        }
        unset($form);
        unset($summary);
        unset($checktimeDatas);
        unset($signDatas);
        unset($checkcontentDatas);
        unset($sigPatientDatas);

        if (!empty($gather)) {
            foreach ($gather as $k => $v) {
                //添加表格
                $tableTitleName = '('.$randomDatas[$k]['random_name'].')汇总表单';
                $section->addText($tableTitleName,'tableTitleStyle',['alignment'=>'center']);
                $section->addTextBreak(1);//换行
                $gatherTable = $section->addTable('myOwnTableStyle');//添加表格
                //添加表头(数字代表宽度)
                foreach($v as $vKey=>$vInfo){
                    $gatherTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                    foreach($vInfo as $vInfo_key=>$vInfo_value){
                        if($vKey == 0){
                            $gatherTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText($vInfo_value,'bStyle',['alignment'=>'center']);
                        }else{
                            if($vInfo_key < 3 || ($vInfo_key >= 3 && !empty($vInfo_value))){
                                $gatherTable->addCell(3000)->addText($vInfo_value,'cStyle',['alignment'=>'center']);
                            }else{
                                $gatherTable->addCell(3000,['bgColor'=>'FFB5B5'])->addText($vInfo_value,'cStyle',['alignment'=>'center']);
                            }
                        }
                        unset($vInfo[$vInfo_key]);
                        unset($v[$vKey][$vInfo_key]);
                        unset($gather[$k][$vKey][$vInfo_key]);
                    }
                    unset($v[$vKey]);
                    unset($gather[$k][$vKey]);
                }
                $section->addTable($gatherTable);
                $section->addTextBreak(1);//换行
                unset($gatherTable);
                unset($tableTitleName);
                unset($gather[$k]);
            }
        }
        unset($gather);
        unset($randomDatas);

        //报告日期
        $reportDate = substr($send_data['create_time'],0,4).'年'.substr($send_data['create_time'],4,2).'月'.substr($send_data['create_time'],6,2).'日';
        $section->addText('报告日期：'.$reportDate,'bStyle',['alignment'=>'right']);
        $section->addTextBreak(1);//换行
        unset($reportDate);

        //生成文件名称
        $fileName = $itemName . "_数据管理阶段报告_" . $send_data['create_time'] . '.docx';

        //配置导出
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) mkdir($path, 0777, true);
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord , 'Word2007');//保存到服务器
        $objWriter->save($path.'/'.$fileName);//保存word文档到指定路径

        //设置header头
        header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        header('Content-Disposition: attachment;filename="' . $fileName . '"');
        header('Content-Transfer-Encoding: binary');
        header('Cache-Control: must-revalidate');
        header('Cache-Control: max-age=0');
        header('Pragma: public');

        ob_clean();
        flush();
        unset($fileName);
        unset($path);
        unset($objWriter);
        unset($phpWord);
        unset($section);
        unset($item_id);
        unset($itemsig_id);
        unset($patient_status);
        unset($patient_ids);

    }

    /**
     * Notes:(新)项目数据管理阶段报告导出(Word)
     * User: lltyy
     * DateTime: 2024/5/13 11:21
     *
     * @param $data
     * @return mixed
     * @throws \Exception
     */
    public function newitemdatareport($send_data)
    {
        $send_data['create_time'] = isset($send_data['create_time']) && !empty($send_data['create_time']) ? $send_data['create_time'] : date('YmdHis',time());
        $item_id = isset($send_data['item_id']) && !empty($send_data['item_id']) ? $send_data['item_id'] : 0;
        $itemsig_id = isset($send_data['itemsig_ids']) && !empty($send_data['itemsig_ids']) ? $send_data['itemsig_ids'] : '';
        $patient_status = isset($send_data['patient_status']) && !empty($send_data['patient_status']) ? $send_data['patient_status'] : '10';
        $patient_ids = isset($send_data['patient_ids']) && !empty($send_data['patient_ids']) ? $send_data['patient_ids'] : '';

        if (empty($item_id)) return $this->RenderApiJson()->Error(StatusCode::E_FIELD_VALIDATOR, '参数不正确');


        //查询项目详情
        $iteminfo = $this->LocalService()->itemInfo->fetchOne(['where'=>[
            'is_del' => 0,
            'id' => $item_id,
        ],'columns'=>['id', 'name','var_name','plan_joingroup']]);

        //获取入组受试者
        $randomSigPatientDatas = [];//分组下的受试者
        $monthPatientDatas = [];//月份下入组数量
        $sigPatientCount = [];//中心下患者数量
        $patient_where = [
            'is_del' => 0,
            'item_id' => $item_id,
            new Operator('joining_date', Operator::OP_GT, 0),
        ];
        if (!empty($itemsig_id)){
            $patient_where['itemsig_id'] = explode(',', $itemsig_id);
        }
        if (!empty($patient_ids)){
            $patient_where['id'] = explode(',', $patient_ids);
        }
        if ($patient_status != 10 || strlen($patient_status) > 2) {
            $patient_where['patient_status'] = explode(',', $patient_status);
        }
        $patientCount = $this->LocalService()->patient->getCount($patient_where);
        $patientPages = ceil($patientCount / 10000);
        if ($patientPages > 0) {
            $patientDatas = $this->yieldData($patientPages,$this->LocalService()->patient, $patient_where,['id', 'itemsig_id','joining_date', 'patient_name', 'patient_number'],['itemsig_id','patient_order','id']);
        }
        unset($patient_where);
        unset($patientCount);
        unset($patientPages);
        if(!empty($patientDatas)){
            foreach($patientDatas as $patientData){
                if(!empty($patientData)) {
                    foreach ($patientData as $patientKey => $patient) {
                        $patient_random = is_null($patient['random_id']) || empty($patient['random_id']) ? 0 : $patient['random_id'];
                        $randomSigPatientDatas[$patient_random][] = $patient;
                        unset($patient_random);
                        //中心患者数
                        $sigPatientCount[$patient['itemsig_id']] = isset($sigPatientCount[$patient['itemsig_id']]) && !empty($sigPatientCount[$patient['itemsig_id']]) ? $sigPatientCount[$patient['itemsig_id']] : 0;
                        $sigPatientCount[$patient['itemsig_id']] += 1;
                        //月份入组例数
                        $patient_month = date('Y-m', $patient['joining_date']);
                        $monthPatientDatas[$patient_month] = isset($monthPatientDatas[$patient_month]) && !empty($monthPatientDatas[$patient_month]) ? $monthPatientDatas[$patient_month] : 0;
                        $monthPatientDatas[$patient_month] += 1;
                        unset($patient_month);
                        unset($patientData[$patientKey]);
                    }
                }
            }
        }
        unset($patientDatas);

        $phpWord = new \PhpOffice\PhpWord\PhpWord();
        $phpWord->addFontStyle('cStyle',array('name' => '宋体','size'=>11));//内容样式
        $phpWord->addFontStyle('bStyle',array('name' => '宋体','size'=>13,'bold'=>true));//加粗样式
        $phpWord->addFontStyle('titleStyle',array('name' => '宋体','size'=>16,'bold'=>true));//标题样式
        $phpWord->addFontStyle('tableTitleStyle',array('name' => '宋体','size'=>14,'bold'=>true));//表格标题样式
        //表格样式
        $styleTable = array('borderSize'=>6,'alignment'=>'center','cellMargin'=>80);
        $phpWord->addTableStyle('myOwnTableStyle',$styleTable);
        unset($styleTable);

        $section = $phpWord->addSection([
            'orientation'=>\PhpOffice\PhpWord\Style\Section::ORIENTATION_LANDSCAPE //横向
        ]);//创建新页面

        //标题
        $section->addText('('.$iteminfo['name'].')项目数据管理阶段报告','titleStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行


        //=======================【入组例数列表】 START ==========================================================================================
        $item_group = !empty($iteminfo['plan_joingroup']) ? $iteminfo['plan_joingroup'] : '';
        $section->addText('方案入组例数：'.$item_group,'bStyle',['alignment'=>'left']);
        $section->addTextBreak(1);//换行

        //入组例数列表 表格
        $section->addText('入组例数列表','tableTitleStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行
        $sigGroupTable = $section->addTable('myOwnTableStyle');//添加表格
        $sigGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
        //添加表头(数字代表宽度)
        $sigGroupTable->addCell(2000,['bgColor'=>'d0d0d0'])->addText('中心号','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(5000,['bgColor'=>'d0d0d0'])->addText('中心名称','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('计划入组例数','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('入组例数','bStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('入组完成比例','bStyle',['alignment'=>'center']);

        //获取项目中心
        $all_sig_group_count = 0;
        $signDatas = [];
        $sigBarLabelList = $sigBarValueList = [];//入组例数列表 柱状图
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);
        if(!empty($itemsignatoryDatas)){
            foreach ($itemsignatoryDatas as $itemsignatoryKey => $itemsignatoryData) {
                $sig_group_patient = isset($sigPatientCount[$itemsignatoryData['value']]) && !empty($sigPatientCount[$itemsignatoryData['value']]) ? $sigPatientCount[$itemsignatoryData['value']] : 0;
                $sig_plangroup_patient = !empty($itemsignatoryData['plan_joingroup']) ? $itemsignatoryData['plan_joingroup'] : 0;
                $sig_group_ratio = !empty($sig_group_patient) && !empty($sig_plangroup_patient) ? floor(($sig_group_patient/$sig_plangroup_patient)*100) : '';
                $signDatas[$itemsignatoryData['value']] = $itemsignatoryData['number'];
                if(!empty($sig_group_patient)){
                    $sig_plangroup_patient_show = !empty($sig_plangroup_patient) ? $sig_plangroup_patient : '';
                    $sig_group_patient_show = !empty($sig_group_patient) ? $sig_group_patient : '';
                    $sig_group_ratio_show = !empty($sig_group_ratio) ? $sig_group_ratio.'%' : '';
                    $sigBarLabelList[] = $itemsignatoryData['label'];
                    $sigBarValueList[] = $sig_group_patient;


                    //添加【入组例数列表】内容
                    $sigGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                    //添加表头(数字代表宽度)
                    $sigGroupTable->addCell(2000)->addText($itemsignatoryData['number'],'cStyle',['alignment'=>'center']);
                    $sigGroupTable->addCell(5000)->addText($itemsignatoryData['label'],'cStyle',['alignment'=>'center']);
                    $sigGroupTable->addCell(3000)->addText($sig_plangroup_patient_show,'cStyle',['alignment'=>'center']);
                    $sigGroupTable->addCell(3000)->addText($sig_group_patient_show,'cStyle',['alignment'=>'center']);
                    $sigGroupTable->addCell(3000)->addText($sig_group_ratio_show,'cStyle',['alignment'=>'center']);

                    unset($sig_plangroup_patient_show);
                    unset($sig_group_patient_show);
                    unset($sig_group_ratio_show);
                }
                $all_sig_group_count += $sig_group_patient;
                unset($sig_group_patient);
                unset($sig_plangroup_patient);
                unset($sig_group_ratio);
                unset($itemsignatoryDatas[$itemsignatoryKey]);
            }
        }
        unset($sigPatientCount);
        unset($itemsignatoryDatas);

        //添加【入组例数列表】内容 - 合计
        $all_sig_group_count = !empty($all_sig_group_count) ? $all_sig_group_count : '';
        $sigGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
        //添加表头(数字代表宽度)
        $sigGroupTable->addCell(2000)->addText('','cStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(5000)->addText('总计','cStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000)->addText($item_group,'cStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000)->addText($all_sig_group_count,'cStyle',['alignment'=>'center']);
        $sigGroupTable->addCell(3000)->addText('','cStyle',['alignment'=>'center']);
        unset($all_sig_group_count);
        unset($item_group);
        $section->addTable($sigGroupTable);
        $section->addTextBreak(1);//换行
        unset($sigGroupTable);
        //入组例数列表 柱状图
        if(!empty($sigBarLabelList)){
            $sigChart = $section->addChart('bar', $sigBarLabelList, $sigBarValueList, [
                'width' => '6000000',
                'height' => '3000000',
                'showAxisLabels' => true,
                'dataLabelOptions' => [
                    'showVal' => false,
                    'showCatName' => false
                ]
            ]);
            $sigChart->getStyle()->setShowGridY();
            $section->addTextBreak(1);//换行
            unset($sigChart);
        }
        unset($sigBarLabelList);
        unset($sigBarValueList);
        //=======================【入组例数列表】 END =============================================================================================

        //=======================【项目入组总进度】 START ==========================================================================================
        $section->addText('项目入组总进度','tableTitleStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行
        $monthGroupTable = $section->addTable('myOwnTableStyle');//添加表格
        $monthGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
        //添加表头(数字代表宽度)
        $monthGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('月份','bStyle',['alignment'=>'center']);
        $monthGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('当月入组例数合计','bStyle',['alignment'=>'center']);
        $monthGroupTable->addCell(3000,['bgColor'=>'d0d0d0'])->addText('总计入组','bStyle',['alignment'=>'center']);
        $monthBarLableList = $monthBarValueList = [];//项目入组总进度 柱状图数据
        if(!empty($monthPatientDatas)){
            $preCount = 0;
            ksort($monthPatientDatas);
            foreach($monthPatientDatas as $monthKey=>$monthDataCount){
                $monthBarLableList[] = $monthKey;
                $monthBarValueList[] = $monthDataCount;
                $preCount += $monthDataCount;
                $monthDataCountShow = !empty($monthDataCount) ? $monthDataCount : '';
                $preCountShow = !empty($preCount) ? $preCount : '';
                $monthGroupTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                //添加表头(数字代表宽度)
                $monthGroupTable->addCell(3000)->addText($monthKey,'cStyle',['alignment'=>'center']);
                $monthGroupTable->addCell(3000)->addText($monthDataCountShow,'cStyle',['alignment'=>'center']);
                $monthGroupTable->addCell(3000)->addText($preCountShow,'cStyle',['alignment'=>'center']);
                unset($preCountShow);
                unset($monthDataCountShow);
                unset($monthPatientDatas[$monthKey]);
            }
            unset($preCount);
        }
        unset($monthPatientDatas);
        $section->addTable($monthGroupTable);
        $section->addTextBreak(1);//换行
        unset($monthGroupTable);

        //项目入组总进度 柱状图
        if(!empty($monthBarLableList)) {
            $monthChart = $section->addChart('column', $monthBarLableList, $monthBarValueList, [
                'width' => '6000000',
                'height' => '3000000',
                'showAxisLabels' => true,
                'dataLabelOptions' => [
                    'showVal' => false,
                    'showCatName' => false
                ]
            ]);
            $monthChart->getStyle()->setShowGridY();
            $section->addTextBreak(1);//换行

            unset($monthChart);
        }
        unset($monthBarLableList);
        unset($monthBarValueList);
        //=======================【项目入组总进度】 END ==========================================================================================


        //=======================【数据录入进度】 START ==========================================================================================

        //数据录入进度
        $section->addText('2、数据录入进度','bStyle',['alignment'=>'left']);
        $section->addTextBreak(1);//换行
        $section->addText('表格中数字表示该访视期对应受试者完成的工作事项，未产生任何数据的已做标红处理。','cStyle',['alignment'=>'center']);
        $section->addTextBreak(1);//换行

        //查询项目表单
        $formIdArr = $this->LocalService()->itemForm->fetchCol('id',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);
        $formIdArr = !empty($formIdArr) ? array_values($formIdArr) : [];

        //查询受试者访视期完成的表单
        $checkFormPatientArr = [];
        $patient_form_where = [
            'is_del' => 0,
            'is_complete' => 1,
            'item_id' => $item_id,
        ];
        if (!empty($itemsig_id)){
            $patient_form_where['itemsig_id'] = explode(',', $itemsig_id);
        }
        if (!empty($patient_ids)){
            $patient_form_where['patient_id'] = explode(',', $patient_ids);
        }
        $patientFormCount = $this->LocalService()->patientForm->getCount($patient_form_where);
        $patientFormPages = ceil($patientFormCount / 10000);
        if ($patientFormPages > 0) {
            $patientFormDatas = $this->yieldData($patientFormPages,$this->LocalService()->patientForm, $patient_form_where,['patient_id', 'checktime_id', 'form_id'],['id']);
        }
        unset($patient_form_where);
        unset($patientFormCount);
        unset($patientPages);
        if(!empty($patientFormDatas)) {
            foreach($patientFormDatas as $patientFormData){
                if(!empty($patientFormData)) {
                    foreach ($patientFormData as $patientFormKey => $patientForm) {
                        if (in_array($patientForm['form_id'], $formIdArr)) {
                            $checkFormPatientArr[$patientForm['checktime_id']][$patientForm['form_id']][$patientForm['patient_id']] = $patientForm['patient_id'];
                        }
                        unset($patientFormData[$patientFormKey]);
                    }
                }
            }
        }
        unset($patientFormDatas);

        //查询当前检查点以及表单
        $checkFormDatas = [];//检查点表单
        $summary = [];//受试者已完成检查点表单数量
        $itemcheck_content_where = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $checkContentCount = $this->LocalService()->patientForm->getCount($itemcheck_content_where);
        $checkContentPages = ceil($checkContentCount / 10000);
        if ($checkContentPages > 0) {
            $checkContentDatas = $this->yieldData($checkContentPages,$this->LocalService()->itemCheckcontent, $itemcheck_content_where,['form_id', 'check_id'],['id']);
        }
        unset($itemcheck_content_where);
        unset($checkContentCount);
        unset($checkContentPages);
        if(!empty($checkContentDatas)) {
            foreach($checkContentDatas as $checkContentData){
                if(!empty($checkContentData)) {
                    foreach ($checkContentData as $checkContentKey => $checkContent) {
                        if (in_array($checkContent['form_id'], $formIdArr)) {
                            $checkFormDatas[$checkContent['check_id']][$checkContent['form_id']] = $checkContent['form_id'];
                            if (isset($checkFormPatientArr[$checkContent['check_id']]) && isset($checkFormPatientArr[$checkContent['check_id']][$checkContent['form_id']]) && !empty($checkFormPatientArr[$checkContent['check_id']][$checkContent['form_id']])) {
                                foreach ($checkFormPatientArr[$checkContent['check_id']][$checkContent['form_id']] as $checkFormPatientId) {
                                    $summary[$checkFormPatientId][$checkContent['check_id']] = isset($summary[$checkFormPatientId]) && isset($summary[$checkFormPatientId][$checkContent['check_id']]) && !empty($summary[$checkFormPatientId][$checkContent['check_id']]) ? $summary[$checkFormPatientId][$checkContent['check_id']] : 0;
                                    $summary[$checkFormPatientId][$checkContent['check_id']] += 1;
                                }
                                unset($checkFormPatientArr[$checkContent['check_id']][$checkContent['form_id']]);
                            }
                        }
                        unset($checkContentData[$checkContentKey]);
                    }
                }
            }
        }
        unset($checkContentDatas);
        unset($checkFormPatientArr);
        unset($formIdArr);

        //获取该项目下方案分组
        $randomDatas = $this->LocalService()->itemRandom->fetchAll(['where'=> [
            'is_del' => 0,
            'item_id' => $item_id,
        ],'columns'=>['id', 'random_name', 'type'],'order'=>['random_order','id']]);
        if(!empty($randomDatas)){
            //查询项目检查点
            $randomChecktimeDatas = [];//分组下的检查点信息
            $checktimeDatas = $this->LocalService()->itemChecktime->fetchAll(['where'=> [
                'is_del' => 0,
                'item_id' => $item_id,
            ],'columns'=>['id', 'check_name', 'random_id'],'order'=>['random_id','check_order','id']]);
            if(!empty($checktimeDatas)){
                foreach($checktimeDatas as $checktimeKey=>$checktimeData){
                    $randomChecktimeDatas[$checktimeData['random_id']][] = $checktimeData;
                    unset($checktimeDatas[$checktimeKey]);
                }
            }
            unset($checktimeDatas);

            //获取患者隐私信息
            $hidePatientAttr = $this->LocalService()->patientattrs->fetchCol('attr_field',[
                'is_del' => 0,
                'item_id' => $item_id,
                'is_hide' => 1,
            ]);
            $hidePatientAttr = array_values($hidePatientAttr);
            foreach ($randomDatas as $randomKey => $randomData) {
                //创建表格
                $section->addText('(' . $randomData['random_name'] . ')汇总表单', 'tableTitleStyle', ['alignment' => 'center']);
                $section->addTextBreak(1);//换行
                $gatherTable = $section->addTable('myOwnTableStyle');//添加表格

                $headData = ['中心编号'];//表头
                $firstData = ['应填表单数量'];
                if (!in_array('number', $hidePatientAttr)) {
                    $headData[] = '受试者筛选号';
                    $firstData[] = '';
                }
                if (!in_array('name', $hidePatientAttr)) {
                    $headData[] = '受试者姓名';
                    $firstData[] = '';
                }
                //访视期表头以及对应访视期应填写表单情况
                if (isset($randomChecktimeDatas[$randomData['id']]) && !empty($randomChecktimeDatas[$randomData['id']])) {
                    foreach ($randomChecktimeDatas[$randomData['id']] as $randomChecktime) {
                        $headData[] = $randomChecktime['check_name'];
                        //检查点应填表单数量
                        $firstData[] = isset($checkFormDatas[$randomChecktime['id']]) && !empty($checkFormDatas[$randomChecktime['id']]) ? count(array_values($checkFormDatas[$randomChecktime['id']])) : 0;
                    }
                }

                //添加表头信息
                $gatherTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                foreach($headData as $headDataKey=>$head){
                    $gatherTable->addCell(3000, ['bgColor' => 'd0d0d0'])->addText($head, 'bStyle', ['alignment' => 'center']);
                    unset($headData[$headDataKey]);
                }
                unset($headData);

                //添加 应填表单数量 信息
                $gatherTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                foreach($firstData as $firstDataKey=>$first){
                    if ($firstDataKey < 3 || ($firstDataKey >= 3 && !empty($first))) {
                        $gatherTable->addCell(3000)->addText($first, 'cStyle', ['alignment' => 'center']);
                    } else {
                        $gatherTable->addCell(3000, ['bgColor' => 'FFB5B5'])->addText($first, 'cStyle', ['alignment' => 'center']);
                    }
                    unset($firstData[$firstDataKey]);
                }
                unset($firstData);

                //添加 中心受试者访视期表单完成信息
                $random_sig_patients = [];
                if(isset($randomSigPatientDatas[$randomData['id']]) && !empty($randomSigPatientDatas[$randomData['id']])){
                    $random_sig_patients = $randomSigPatientDatas[$randomData['id']];
                    unset($randomSigPatientDatas[$randomData['id']]);
                }
                if($randomData['type'] == 1 && isset($randomSigPatientDatas[0]) && !empty($randomSigPatientDatas[0])){
                    $random_sig_patients = !empty($random_sig_patients) ? array_merge($random_sig_patients,$randomSigPatientDatas[0]) : $randomSigPatientDatas[0];
                    unset($randomSigPatientDatas[0]);
                }
                if (!empty($random_sig_patients)) {
                    foreach($random_sig_patients as $randomSigPatientKey=>$randomSigPatient){
                        $contentData = [];
                        $contentData[] = isset($signDatas[$randomSigPatient['itemsig_id']]) && $signDatas[$randomSigPatient['itemsig_id']] != '' ? $signDatas[$randomSigPatient['itemsig_id']] : '';
                        if (!in_array('number', $hidePatientAttr)) {
                            $contentData[] = $randomSigPatient['patient_number'];
                        }
                        if (!in_array('name', $hidePatientAttr)) {
                            $contentData[] = $randomSigPatient['patient_name'];
                        }
                        if (isset($randomChecktimeDatas[$randomData['id']]) && !empty($randomChecktimeDatas[$randomData['id']])) {
                            foreach ($randomChecktimeDatas[$randomData['id']] as $randomChecktime1) {
                                //受试者访视期表单完成数量
                                $contentData[] = isset($summary[$randomSigPatient['id']]) && isset($summary[$randomSigPatient['id']][$randomChecktime1['id']]) && !empty($summary[$randomSigPatient['id']][$randomChecktime1['id']]) ? $summary[$randomSigPatient['id']][$randomChecktime1['id']] : 0;
                            }
                        }

                        //受试者访视期表单完成情况
                        $gatherTable->addRow(90);//添加一行（addRow执行后才可执行addCell给本行添加列，括号内数字代表高度）
                        foreach ($contentData as $content_key => $content_value) {
                            if ($content_key < 3 || ($content_key >= 3 && !empty($content_value))) {
                                $gatherTable->addCell(3000)->addText($content_value, 'cStyle', ['alignment' => 'center']);
                            } else {
                                $gatherTable->addCell(3000, ['bgColor' => 'FFB5B5'])->addText($content_value, 'cStyle', ['alignment' => 'center']);
                            }
                            unset($contentData[$content_key]);
                        }
                        unset($contentData);
                        unset($random_sig_patients[$randomSigPatientKey]);
                    }
                }
                unset($random_sig_patients);
                unset($k);
                if (isset($randomChecktimeDatas[$randomData['id']])) {
                    unset($randomChecktimeDatas[$randomData['id']]);
                }

                $section->addTable($gatherTable);
                $section->addTextBreak(1);//换行
                unset($gatherTable);
                unset($randomDatas[$randomKey]);
            }
            unset($hidePatientAttr);
            unset($randomChecktimeDatas);
        }
        unset($signDatas);
        unset($checkFormDatas);
        unset($summary);
        unset($randomDatas);


        //报告日期
        $reportDate = substr($send_data['create_time'],0,4).'年'.substr($send_data['create_time'],4,2).'月'.substr($send_data['create_time'],6,2).'日';
        $section->addText('报告日期：'.$reportDate,'bStyle',['alignment'=>'right']);
        $section->addTextBreak(1);//换行
        unset($reportDate);

        //生成文件名称
        $fileName = $iteminfo['name'] . "_数据管理阶段报告_" . $send_data['create_time'] . '.docx';

        //配置导出
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) mkdir($path, 0777, true);
        $objWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord , 'Word2007');//保存到服务器
        $objWriter->save($path.'/'.$fileName);//保存word文档到指定路径

        //设置header头
        header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        header('Content-Disposition: attachment;filename="' . $fileName . '"');
        header('Content-Transfer-Encoding: binary');
        header('Cache-Control: must-revalidate');
        header('Cache-Control: max-age=0');
        header('Pragma: public');

        ob_clean();
        flush();
        unset($fileName);
        unset($path);
        unset($objWriter);
        unset($phpWord);
        unset($section);
        unset($item_id);
        unset($itemsig_id);
        unset($patient_status);
        unset($patient_ids);
        unset($iteminfo);

    }

    /**
     * 导出项目有默认值的选项
     */
    public function defaultoptions($data)
    {
        $item_id = $data['item_id'];

        $item_id = [107,1084,1085,2178,2267,2305,2349,2354,2366];//scitrials

//        $item_id = [72,74,76,77,83,101,103,105,106,108,160,270,280];//5mc

        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $data['item_id'],
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);
        $fileName = $itemInfo['name'] .'超窗-未查'. '-' . $data['create_time'] . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '病例收集系统');
//        $fileObject = $xlsxObject->fileName($fileName, '晚期患者_同种异体过继免疫细胞治');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        foreach($item_id as $key=>$value){
            $item_name = $this->LocalService()->itemInfo->getOneFieldVal('name',[
                'id' => $value,
            ]);

            $formDatas = $this->getform($value, 0);

            $field = $this->LocalService()->itemFormField->fetchAll(['where'=> [
                'item_id' => $value,
                'is_del' => 0,
            ],'columns'=>['id','name','parent']]);

            $fieldDatas = [];
            foreach($field as $k=>$v){
                $fieldDatas[$v['id']] = $v;
            }
            $form_id = implode(',',array_column($formDatas,'id'));
            if(empty($form_id)){
                var_dump($value,$form_id);die;
            }
            $radio = $this->LocalService()->itemFormFieldRadio->fetchAll(['where'=> [
                'form_id' => explode(',', $form_id),
            ],'columns'=>['id','is_check','form_id','field_id','order'=>'form_id']]);

            $header = [];

            if($key == 0){
                $ks = 0;
                $data = [];
            }else{
                $ks = 1;
                $data = [['表单名称','字段名称','选项名称','是否默认']];
            }

            foreach($radio as $k=>$v){

                //表单名称
                $data[$ks][] = $formDatas[$v['form_id']]['name'];
                //字段名称
                $data[$ks][] = $fieldDatas[$fieldDatas[$v['field_id']]['parent']]['name'];
                //选项名称
                $data[$ks][] = $fieldDatas[$v['field_id']]['name'];
                $data[$ks][] = ($v['is_check'] == 1) ? '是' : '否';
                ++$ks;
            }
            if($key == 0){
                $fileObject->header(['表单名称','字段名称','选项名称','是否默认'])->data($data);
                $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
            }else{

                $item_name = str_replace("/", '-', $item_name);
                $item_name = str_replace("[", '【', $item_name);
                $item_name = str_replace("]", '】', $item_name);
                $item_name = str_replace("？", '', $item_name);
                $item_name = str_replace("（", '【', $item_name);
                $item_name = str_replace("）", '】', $item_name);
                $item_name = str_replace(" ", '', $item_name);
                $item_name = mb_substr($item_name, 0, 16);
                if (mb_strlen($item_name) > 16) {
                    $item_name .= ".....";
                }
                $fileObject->addSheet($item_name)->data($data);
            }
        }

        $filePath = $fileObject->output();
    }

    /**
     * Notes: 电话随访信息
     * User: lltyy
     * DateTime: 2024/6/14 11:44
     *
     * @param $data
     * @throws \Exception
     */
    public function telformdata($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID
        $patient_status = isset($send_data['patient_status']) && !empty($send_data['patient_status']) ? $send_data['patient_status'] : '10';
        $create_time = $data['create_time'];       //创建时间

        //获取电话随访表单
        $form_ids = '';
        $form_group_arr = $this->LocalService()->dictionaryFormGroup->fetchCol('id',[
            'is_del' => 0,
            'code' => 'Telephone_Follow_Up',
        ]);
        $form_group_arr = !empty($form_group_arr) ? array_values($form_group_arr) : [];
        if(!empty($form_group_arr)){
            $form_id_arr = $this->LocalService()->itemForm->fetchCol('id',[
                'is_del' => 0,
                'item_id' => $item_id,
                'group_id' => $form_group_arr,
            ]);
            $form_id_arr = !empty($form_id_arr) ? array_values($form_id_arr) : [];

            $form_ids = !empty($form_id_arr) ? implode(',',$form_id_arr) : '';
        }

        //当前项目阶段
        $StageDatas = $this->getItemstage($item_id);

        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //获取当前申请的中心
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, $patient_status);

        $itemWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $itemWhere['columns'] = ['id', 'name', 'number'];
        $itemInfo = $this->LocalService()->itemInfo->fetchOne($itemWhere);

        $formData = [];

        //处理表单数据
        if ($form_ids != '') {
            list($catalogue, $formData) = $this->formdataHandle($patientDatas, $checktimeDatas, $StageDatas, $itemsignatoryDatas, $item_id, $form_ids, $patient_id, $itemInfo['number'], $itemsig_id,1);
        }
        
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = $itemInfo['name'] . '_电话随访列表_' . $create_time . '.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, 'eCRF表单');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
        $fileObject->header(['表单名称', '表单变量名'])->data($catalogue);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        //循环指标数据生成sheet
        if(!empty($formData)){
            foreach ($formData as $k => $v) {
                //截取sheet名称长度
                $sheetName = mb_substr($k, 0, 16);
                if (mb_strlen($k) > 16) {
                    $sheetName .= ".....";
                }
                $fileObject->addSheet($sheetName)->data($formData[$k]);
                $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
            }
        }

        //输出数据
        $filePath = $fileObject->output();
    }

    public function doctoradvice($data)
    {
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID
        $patient_id = $data['patient_ids'] ?: 0;       //受试者ID

        $doctoradvice_group = $this->LocalService()->itemInfo->getOneFieldVal('doctoradvice_group', [
            'is_del' => 0,
            'id' => $item_id,
        ]);

        $header = !empty($doctoradvice_group) ? Exportenum::Doctoradvice_category : Exportenum::Doctoradvice;

        $categoryName = [];
        if($doctoradvice_group == 1){
            $drugCategoryId = $this->LocalService()->collectDrug->fetchCol('category_id','is_del = 0');

            if(!empty($drugCategoryId)){
                //药物分类
                $categoryName = $this->LocalService()->collectDrugcategory->fetchCol('category_name','is_del = 0');
            }

        }

        //查询项目详情
        $iteminfoWhere['where'] = [
            'is_del' => 0,
            'id' => $item_id,
        ];
        $iteminfoWhere['columns'] = ['id', 'name','number'];
        $iteminfo = $this->LocalService()->itemInfo->fetchOne($iteminfoWhere);

        //配置导出
        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $xlsxObject = new \Vtiful\Kernel\Excel($config);

        $fileName = $iteminfo['name'] . "合并用药识别结果" . '-' . $data['create_time'] . '.xlsx';

        $fileObject = $xlsxObject->fileName($fileName, 'eCRF');

        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();


        //查询项目医嘱、出院医嘱表单
        $formData= $this->LocalService()->itemForm->fetchAll([
            'where'=> [
                'is_del' => 0,
                'item_id' => $item_id,
                'info_collect_type' => [2, 3],
            ],
            'columns'=>['id','name','var_name'],
            'order'=>'order'
        ]);
        $eCRF = [];
        foreach($formData as $k=>$v){
            $eCRF[$k+1][] = $v['name'];
            $eCRF[$k+1][] = $v['var_name'];
        }

        $fileObject->header(['表单', '变量名'])->data($eCRF);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);


        $lockWhere['where'] = [
            'is_del' => 0,
            'is_lock' => 1,
            'item_id' => $item_id,
            new Operator('drug_id', Operator::OP_NE, '')
        ];
        if(!empty($itemsig_id)) $lockWhere['where']['itemsig_id'] = explode(',', $itemsig_id);
        if(!empty($patient_id)) $lockWhere['where']['patient_id'] = explode(',', $patient_id);

        $lockWhere['columns'] = ['id','item_id','patient_id','annex_id','item_id','dosage_num','form_id','itemsig_id','checktime_id',
            'drug_id','medical_date','end_date','dosage_unit','dosage_way','dosage_times','is_dispensary','batch','dualtherapy_type','result_type'];
        $lockWhere['order'] = ['itemsig_id','patient_id'];
        $lockDatas = $this->LocalService()->doctoradviceOriginal->fetchAll($lockWhere);
        if(empty($lockDatas)) $filePath = $fileObject->output();

        //获取当前申请的中心
        $itemsignatory = $this->LocalService()->itemSignatory->itemSigninfo($itemsig_id, $item_id, 0);

        $itemsignatoryDatas = ArrayHelper::index($itemsignatory, 'value');

        unset($itemsignatory);

        //获取当前申请的受试者 按中心分组
        $patientDatas = $this->getItempatinet($item_id, $itemsig_id, $patient_id, 9);

        //当前项目检查点
        $checktimeDatas = $this->getItemchecktime($item_id);

        //受试者编号是否为隐私字段
        $attrnumber = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'number',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        //受试者姓名是否为隐私字段
        $attrname = $this->LocalService()->patientattrs->fetchCol('id', [
            'is_hide' => 0,
            'attr_field' => 'name',
            'is_del' => 0,
            'item_id' => $item_id,
        ]);//获取项目名称

        $drugData = $this->LocalService()->collectDrug->fetchCol('name',"is_del = 0");

        $takeInfos = $this->LocalService()->collectMedicaltake->fetchAll(['where'=>'is_del = 0 ','columns'=>['id','english','name']]);
        $takeNameArr = [];
        if(!empty($takeInfos)){
            $takeNameArr = ArrayHelper::index($takeInfos, 'id');
            unset($takeInfos);
        }
        foreach($formData as $key=>$value){
            $data = [];
            $data = $header;
            $i = 1;
            foreach($lockDatas as $k=>$v){
                if($v['form_id'] != $value['id']) continue;
                //项目号
                $data[$i][] = $iteminfo['number'];
                //中心号
                $data[$i][] = $itemsignatoryDatas[$v['itemsig_id']]['number'];

                $patientInfo = '';
                if (!empty($attrnumber)) {
                    //受试者编号
                    $patientInfo = '【'.$patientDatas[$v['itemsig_id']][$v['patient_id']]['patient_number'].'】';
                }

                if (!empty($attrname)) {
                    //受试者姓名
                    $patientInfo .= $patientDatas[$v['itemsig_id']][$v['patient_id']]['patient_name'];
                }

                //受试者
                $data[$i][] = $patientInfo;
                //访视
                $data[$i][] = $checktimeDatas[$v['checktime_id']]['check_name'];

                if($doctoradvice_group == 1) $data[$i][] = !empty($categoryName) && isset($categoryName[$drugCategoryId[$v['drug_id']]]) ? $categoryName[$drugCategoryId[$v['drug_id']]] : '';

                //药物名称
                $data[$i][] = $drugData[$v['drug_id']];
                //开始日期
                $data[$i][] = $v['medical_date'];
                //结束日期
                $data[$i][] = $v['end_date'];
                //剂量
                $data[$i][] = $v['dosage_num'];

                $unit = '';
                if(!empty($v['dosage_unit'])){
                    $dosage_unit = $v['dosage_unit'];
                    $unit = isset($takeNameArr[$dosage_unit]) ? $takeNameArr[$dosage_unit]['name'] : '';
                    if(isset($takeNameArr[$dosage_unit]) && !empty($dosage_unit) && !empty($takeNameArr[$dosage_unit]['english'])) $unit.= '('.$takeNameArr[$dosage_unit]['english'].')';
                }

                //剂量单位
                $data[$i][] = $unit;

                $times = '';
                if(!empty($v['dosage_times'])){
                    $dosage_times = $v['dosage_times'];
                    $times = isset($takeNameArr[$dosage_times])  ? $takeNameArr[$dosage_times]['name'] : '';
                    if(isset($takeNameArr[$dosage_times]) && !empty($dosage_times) && !empty($takeNameArr[$dosage_times]['english'])) $times.= '('.$takeNameArr[$dosage_times]['english'].')';
                }
                //服用频率
                $data[$i][] = $times;

                $way = '';
                if(!empty($v['dosage_way'])){
                    $dosage_way = $v['dosage_way'];
                    $way = isset($takeNameArr[$dosage_way])  ? $takeNameArr[$dosage_way]['name'] : '';
                    if(isset($takeNameArr[$dosage_way]) && !empty($dosage_way) && !empty($takeNameArr[$dosage_way]['english'])) $way.= '('.$takeNameArr[$dosage_way]['english'].')';
                }
                //服用方式
                $data[$i][] = $way;
                //出院带药
                $data[$i][] = (!empty($v['is_dispensary'])) ? '是' : '否';
                ++$i;
            }
            $fileObject->addSheet($value['name'])->data($data);
            $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        }
        $filePath = $fileObject->output();
    }

    /**
     * Notes:导出逻辑核查质疑
     * @param
     * @return
     * @author haojinhua
     * @date 2024-08-27
     */
    public function logerrorData($data){
        //删除pdf文件夹
        /* $down_pdf_path  =  APP_PATH . '/data/exportFile';
         $this->DelDirHandle($down_pdf_path);
         die;*/
        $item_id = $data['item_id'];       //项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0;       //中心ID

        //获取逻辑核查质疑信息
        $model = new ExportModel();
        $datas = $model->exportLogicError($data);  //print_r($datas);die;
        unset($model);

        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $itemName = $this->LocalService()->itemInfo->getOneFieldVal('name',[
            'is_del' => 0,
            'id' => $item_id,
        ]);
        $fileName = $itemName . '逻辑核查质疑导出-' . $data['create_time'] . '.xlsx';
        unset($itemName);
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '逻辑核查质疑');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $fileObject->header(['项目ID','中心编号','筛选号','访视名称','表单名称','字段名称','序号','质疑内容','质疑时间','质疑发出人员/角色','质疑回复内容','质疑回复时间','质疑回复人员/角色','质疑关闭时间','质疑关闭人员/角色'])->data($datas[0]);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);
        $fileObject->addSheet('图片质疑')->header(['项目ID','中心编号','筛选号','访视名称','表单名称','字段名称','序号','质疑内容','质疑时间','质疑发出人员/角色','质疑回复内容','质疑回复时间','质疑回复人员/角色','质疑关闭时间','质疑关闭人员/角色'])->data($datas[1]);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        $filePath = $fileObject->output();

        unset($fileName);
        unset($wrapStyle);
        unset($headerBgStyle);
        unset($xlsxObject);
        unset($item_id);
        unset($itemsig_id);
        unset($results);
        unset($format);

    }

    public function tmp()
    {
        $formData = $this->LocalService()->itemForm->fetchCol('name',"type = 0 and is_del = 0");
        $keys = array_keys($formData);
        $keysString = implode(', ', $keys);

        $itemDatas = $this->LocalService()->itemInfo->fetchCol('name',"is_del = 0 and fid > 0 and status = 0");

        $checkDatas = $this->LocalService()->itemChecktime->fetchCol('check_name',"is_del = 0");

        $itemIdArr = $this->LocalService()->patientFormContent->fetchCol('item_id',"is_del = 1 and form_id in ($keysString) group by item_id");

        $itemsigIdArr = $this->LocalService()->patientFormContent->fetchCol('itemsig_id',"is_del = 1 and form_id in ($keysString) group by itemsig_id");

        $whereItemSignatory['where'] = ['id'=>$itemsigIdArr];
        $itemSignatoryData = $this->LocalService()->itemSignatory->fetchAll($whereItemSignatory);

        $signatoryId = array_column($itemSignatoryData,'signatory_id');

        $sign_datas = $this->LocalService()->signatoryInfo->fetchcol('info_name',['id'=>$signatoryId]);

        $signatpryInfoDatas = [];
        foreach($itemSignatoryData as $k=>$v){
            $signatpryInfoDatas[$v['id']] = $sign_datas[$v['signatory_id']];
        }

        $patientDatas = $this->LocalService()->patient->fetchAll([
            'where'=>"is_del = 0 and  item_id in (".implode(',',$itemIdArr).")",
            'columns'=>['id','patient_name','patient_number']
        ]);
        $patient = [];
        foreach($patientDatas as $vv){
            $patient[$vv['id']] = $vv;
        }
        unset($patientDatas);

        $contentDatas = $this->LocalService()->patientFormContent->fetchAll([
            'where'=>"is_del = 1 and form_id in ($keysString)",
            'columns'=>['id','item_id','itemsig_id','patient_id','checktime_id',"form_id"]
        ]);
        $arr = [];
        $k = 1;
        foreach ($contentDatas as  $k=>$v){
            if(!isset($patient[$v['patient_id']])) continue;
            if(!isset($itemDatas[$v['item_id']])) continue;
            $arr[$k][] = $itemDatas[$v['item_id']];
            $arr[$k][] = $signatpryInfoDatas[$v['itemsig_id']];
            $arr[$k][] = $patient[$v['patient_id']]['patient_name'].'【'.$patient[$v['patient_id']]['patient_number'].'】';
            $arr[$k][] = $checkDatas[$v['checktime_id']];
            $arr[$k][] = $formData[$v['form_id']];
            ++$k;
        }



        $path = APP_PATH . '/data/exportFile';
        if (file_exists($path) == false) {
            mkdir($path, 0777, true);
        }
        $config = [
            'path' => $path // xlsx文件保存路径
        ];
        $fileName = '一对一表单删除数据--5mc'.'.xlsx';
        $xlsxObject = new \Vtiful\Kernel\Excel($config);
        $fileObject = $xlsxObject->fileName($fileName, '5mc');
        $excelFileHandle = $fileObject->getHandle();
        $format = new Format($excelFileHandle);
        $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
        $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

        $fileObject->header(['项目','中心','受试者','检查点','表单'])->data($arr);
        $fileObject->setRow('A1:ZZ1', 20, $headerBgStyle)->setColumn('A1:ZZ1', 20);

        $filePath = $fileObject->output();
    }

    /**
     * Notes: 导出其他事件
     * @param
     * @return
     * @author haojinhua
     * @date 2025-02-18
     */
    public function itemevent($data){
        $item_id = $data['item_id'];       // 项目ID
        $itemsig_id = $data['itemsig_ids'] ?: 0; // 中心ID

        // 查询数据
        $where = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($itemsig_id)){
            $where['itemsig_id'] = $itemsig_id;
        }

        $where_cond = [
            'where'   => $where,
            'columns' => ['id', 'item_id', 'itemsig_id', 'patient_id', 'event_id', 'create_user_id', 'create_time', 'json_data'],
            'order'   => ['event_order ASC'],
        ];
        $eventdatas = $this->LocalService()->itemPatientevent->fetchAll($where_cond);
        //print_r($eventdatas);die;
        $event_datas = $all_attr_names = [];
        if(!empty($eventdatas)){
            foreach ($eventdatas as $eventdata){
                $old_json_datas = json_decode($eventdata['json_data'],true);
                if(!empty($old_json_datas)){
                    foreach ($old_json_datas as $old_json_data){
                        $all_attr_names[$eventdata['event_id']][$eventdata['id']][] = $old_json_data['attr_name'];
                    }
                }
                $event_datas[$eventdata['event_id']][] = $eventdata;
            }
        }
        unset($eventdatas);

        $down_path = APP_PATH . '/data/exportFile';
        // 检查目录是否存在，如果不存在则创建
        if (!file_exists($down_path)) {
            mkdir($down_path, 0777, true); // 创建目录，设置权限为0777
        }

        // 查询事件及事件对应的属性
        $event_ids = $this->LocalService()->itemPatientevent->fetchCol('event_id', $where);
        $event_ids = array_unique($event_ids);
        // 查询事件的字典项设置及对应的属性
        $attr_where = 'id < 0';
        if (!empty($event_ids)) {
            $attr_where = [
                'is_del' => 0,
                'event_id' => $event_ids,
            ];
        }
        $attr_cond = [
            'where' => $attr_where,
            'columns' => ['id', 'event_id', 'name' => 'attr_name','attr_type','content'],
        ];

        $attr_names = [];
        $attr_types = [];
        $attr_datas = $this->LocalService()->dictionaryEventattr->fetchAll($attr_cond);
        if(!empty($attr_datas)){
            foreach ($attr_datas as $attr_data){
                $attr_names[$attr_data['event_id']][$attr_data['id']] = $attr_data['name'];
                $attr_types[$attr_data['event_id']][$attr_data['id']]['attr_type'] = $attr_data['attr_type'];
                $contents = json_decode($attr_data['content'],true);
                if(!empty($contents)){
                    foreach ($contents as $content){
                        $attr_types[$attr_data['event_id']][$attr_data['id']]['select_name'][$content['select_variable']] = $content['select_name'];
                    }
                }

            }
        }
        //print_r($attr_types);die;
        unset($attr_datas);

        $typecode_datas = $this->LocalService()->dictionaryFormtype->fetchCol('type_code','is_del = 0');

        // 查询事件信息
        $formNameArr = [];
        if (!empty($event_ids)) {
            $formNameArr = $this->LocalService()->dictionaryEventset->fetchCol('event_name', [
                'is_del' => 0,
                'id' => $event_ids,
            ]);
        }

        // 设置导出文件名 获取项目名称
        $item_name = $this->LocalService()->itemInfo->getOneFieldVal('name',[
            'id' => $item_id,
        ]);
        $item_number = $this->LocalService()->itemInfo->getOneFieldVal('number',[
            'id' => $item_id
        ]);
        $fileName = $item_name."其他事件记录导出" . '-' . $data['create_time'] . '.xlsx';

        // 创建 Excel 对象
        $excelObj = new Excel([
            'path' => APP_PATH . '/data/exportFile'
        ]);


        // 定义固定表头
        $prefixHeaders = ['项目编号', '中心编号', '筛选号'];
        $suffixHeaders = ['创建人', '创建时间'];

        // 遍历每个 event_id，创建对应的 Sheet 并填充数据
        if (!empty($event_ids)) {
            //判断传过来的ID是否是大项目ID
            $fid = $this->LocalService()->itemInfo->getOneFieldVal('fid',[
                'id' => $item_id,
            ]);
            $sigNumberArr = $this->LocalService()->itemSignatory->fetchCol('number',[
                'id' => $itemsig_id,
            ]); //中心编号
            //受试者编号数组
            $patientDatas   = $this->LocalService()->patient->fetchDataByKey([
                'item_id' => $item_id,
            ], ['id', 'patient_name', 'patient_number'], ['id'], ['id' => 0]);
            $patientData    = isset($patientDatas['id']) ? $patientDatas['id'] : [];
            //查询人员姓名数组
            $userNameArr = $this->LocalService()->adminUser->fetchCol('realname', 'is_del = 0');
            $sheetIndex = 0;
            foreach ($event_ids as $event_id) {
                // 获取表单名称并处理特殊字符
                $event_form_name = !empty($formNameArr[$event_id]) ? $formNameArr[$event_id] : '';
                $formname = str_replace("/", '-', $event_form_name);
                $formname = str_replace("[", '【', $formname);
                $formname = str_replace("]", '】', $formname);
                $formname = str_replace("？", '', $formname);
                $formname = str_replace("（", '【', $formname);
                $formname = str_replace("）", '】', $formname);
                $formname = str_replace(" ", '', $formname);

                // 获取当前 event_id 对应的动态表头
                $dynamicHeaders = isset($attr_names[$event_id]) && !empty($attr_names[$event_id]) ? $attr_names[$event_id] : [];

                // 合并固定表头和动态表头
                $sheetHeaders = array_merge($prefixHeaders, $dynamicHeaders, $suffixHeaders);
                //print_r($sheetHeaders);die;
                // 获取当前 Sheet 的数据
                $eventDatas = isset($event_datas[$event_id]) && !empty($event_datas[$event_id]) ? $event_datas[$event_id] : [];

                // 初始化或添加新的 Sheet
                if ($sheetIndex == 0) {
                    // 初始化第一个 Sheet
                    $excelFileObj = $excelObj->fileName($fileName, $formname)->header($sheetHeaders);
                    $excelFileHandle = $excelFileObj->getHandle();
                    $format = new Format($excelFileHandle);
                    $wrapStyle = $format->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
                    $headerBgStyle = $format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

                    // 设置第一个 Sheet 的样式
                    $excelFileObj->setRow('A1:' . chr(65 + count($sheetHeaders) - 1) . '1', 20, $headerBgStyle)
                        ->setColumn('A1:E1', 20)
                        ->setColumn('F1:L1', 20)
                        ->freezePanes(1, 1);
                } else {
                    // 添加新的 Sheet
                    $excelFileObj->addSheet($formname)->header($sheetHeaders);
                    $newExcelFileHandle = $excelFileObj->getHandle();
                    $newFormat = new Format($newExcelFileHandle);
                    $newWrapStyle = $newFormat->wrap()->align(Format::FORMAT_ALIGN_LEFT, Format::FORMAT_ALIGN_VERTICAL_TOP)->toResource();
                    $newHeaderBgStyle = $newFormat->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();

                    // 设置新 Sheet 的样式
                    $excelFileObj->setRow('A1:' . chr(65 + count($sheetHeaders) - 1) . '1', 20, $newHeaderBgStyle)
                        ->setColumn('A1:E1', 20)
                        ->setColumn('F1:L1', 20)
                        ->freezePanes(1, 1);
                }
                //print_r($eventDatas);die;
                // 准备数据行
                foreach ($eventDatas as $data) {
                    $rowData = [];
                    // 固定表头数据
                    $rowData[] = $item_number; // 项目ID
                    $sig_number = isset($sigNumberArr[$data['itemsig_id']]) ? $sigNumberArr[$data['itemsig_id']] : '';
                    $rowData[] = $sig_number; // 中心编号
                    $rowData[] = isset($patientData[$data['patient_id']]['patient_number']) ? $patientData[$data['patient_id']]['patient_number'] : ''; // 筛选号
                    //print_r($dynamicHeaders);die;
                    // 动态表头数据
                    //foreach ($dynamicHeaders as $header) {
                        $json_data_arr = json_decode($data['json_data'], true) ?: [];
                        //print_r($json_data_arr);die;
                         $attr_names_arr = isset($all_attr_names[$event_id][$data['id']])&&!empty($all_attr_names[$event_id][$data['id']]) ? $all_attr_names[$event_id][$data['id']] : [];
                         $array_diff_attr = array_diff($dynamicHeaders,$attr_names_arr);
                        if(!empty($json_data_arr)){
                            foreach ($json_data_arr as $json_data){
                                if (in_array($json_data['attr_name'],$dynamicHeaders)) {
                                    //获取属性类型
                                    $attr_type = isset($attr_types[$event_id][$json_data['id']]['attr_type']) && !empty($attr_types[$event_id][$json_data['id']]['attr_type']) ? $attr_types[$event_id][$json_data['id']]['attr_type'] :0;
                                    $type_code = isset($typecode_datas[$attr_type]) && !empty($typecode_datas[$attr_type]) ? $typecode_datas[$attr_type] : '';
                                    if(in_array($type_code,['upload_file','upload_img'])){
                                        $attr_value = json_decode($json_data['attr_value']);
                                        $json_data['attr_value'] = !empty($attr_value) ? '已上传图片/文件' :'';
                                    }

                                    if(in_array($type_code,['radio','checkbox','select'])){
                                        if($type_code == 'checkbox' && !empty($json_data['attr_value'])){
                                            $attr_v1 = '';
                                            foreach ($json_data['attr_value']  as $attr_values){
                                                $attr_v2 = isset($attr_types[$event_id][$json_data['id']]['select_name'][$attr_values]) && !empty($attr_types[$event_id][$json_data['id']]['select_name'][$attr_values]) ? $attr_types[$event_id][$json_data['id']]['select_name'][$attr_values]:'';
                                                $attr_v1 .=$attr_v2.',';
                                            }
                                            $json_data['attr_value'] = trim($attr_v1,',');
                                        }else{
                                            $json_data['attr_value'] = isset($attr_types[$event_id][$json_data['id']]['select_name'][$json_data['attr_value']]) && !empty($attr_types[$event_id][$json_data['id']]['select_name'][$json_data['attr_value']]) ? $attr_types[$event_id][$json_data['id']]['select_name'][$json_data['attr_value']]:'';
                                        }
                                    }
                                }

                                $value = $json_data['attr_value']; // 找到对应的值

                                $rowData[] = $value;
                            }
                        }
                        //print_r($array_diff_attr);die;
                        if(!empty($array_diff_attr)){   //针对新增的字典项 但是历史数据里没设置过的
                            foreach ($array_diff_attr as $array_diff){
                                $rowData[] = '';
                            }
                        }

                    //}
                    // 添加创建人和创建时间
                    $rowData[] = isset($userNameArr[$data['create_user_id']]) ? $userNameArr[$data['create_user_id']] : '';
                    $rowData[] = date('Y-m-d H:i:s', $data['create_time']);

                    //print_r($rowData);die;
                    // 写入数据行到当前 Sheet
                    $excelFileObj->checkoutSheet($formname)->data([$rowData]);
                }

                $sheetIndex++;
            }

            unset($sig_number);
            unset($patientDatas);
            unset($patientData);
            unset($userNameArr);
            unset($formNameArr);
            unset($typecode_datas);
        }
        // 输出 Excel 文件
        $filePath = $excelFileObj->output();
    }

    /**
     * Notes: 通过yield从数据库中分批取出数据，也是为了防止数据量过大一次性抓取数据，导致内存溢出的情况
     * User: lltyy
     * DateTime: 2025/6/6 12:12
     *
     * @param $totalPage
     * @param $tableService
     * @param $where
     * @param $columns
     * @param string[] $order
     * @return \Generator
     */
    public function yieldData($totalPage,$tableService, $where,$columns,$order=['id'])
    {
        $limit = 10000;
        for ($i = 1; $i <= $totalPage; $i++) {
            $offset = ($i - 1) * $limit;
            $cond = [
                'where'   => $where,
                'columns' => $columns,
                'order'=>$order,
                'limit'   => $limit,
                'offset'  => $offset
            ];
            $datas = $tableService->fetchAll($cond);
            yield $datas;
        }
    }

}