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

namespace Application\Service\DB\Item;

use Application\Service\Extension\Helper\StringHelper;
use Interop\Container\ContainerInterface;
use Laminas\Db\Sql\Predicate\IsNull;
use Laminas\Db\Sql\Predicate\Operator;
use Laminas\Db\Sql\Where;
use Vtiful\Kernel\Format;

class Exportpdf extends \Application\Service\DB\AbstractDb
{
    private $xlsxObject;

    private $fileName;

    private $fileObject;

    private $format;

    private $item_name; //项目编号

    private $item_number; //项目编号

    private $signatoryName; //中心信息

    private $notes = false; //完整注释

    private $patientInfo = []; //受试者信息

    private $form;

    private $randomDatas;

    private $groupDatas;

    private $patientattrs;//受试者筛选号

    private $export_type;//导出类型
    
    private $fieldType;

    private $version;

    private $version_time;

    private $is_applets;

    private $checktime_ids;

    private $itemsig_ids;

    private $DateFormat;

    private $randomAlias;

    private $exportType = [
        '1' => '完整空白CRF',
        '2' => '完整注释',
        '4' => '受试者完整数据CRF',
        '5' => '完整注释CRF(去重)'
    ];


    public function __construct($dbAdapter, ContainerInterface $container)
    {
        $path = APP_PATH . '/data/exportFile';

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

        $this->tableName = 'yikeen_item_exportpdf';
        parent::__construct($dbAdapter, $container);
    }

    //定义各类型的字段类型以及长度
    public const FORM_FIELD_TYPE = [
        1=>'Char(80)',
        2=>'Char(20)',
        3=>'Date(yyyy‐MM‐dd)',
        4=>'Date(yyyy‐MM‐dd H:i)',
        5=>'Date(yyyy‐MM‐dd H:i:s)',
        6=>'int(11)',
        7=>'Decimal(10,1)',
        8=>'Decimal(10,2)',
        9=>'Decimal(10,3)',
        10=>'Char(20)',
        11=>'Char(50)',
        12=>'Char(20)',
        13=>'varchar(100)',
        14=>'varchar(100)',
        15=>'text(0)',
    ];

    //定义各类型的字段类型以及长度
    public const FORM_FIELD_convert = [
        'Date'=>3,
        'DateTimeSecond'=>4,
        'DateTime'=>5,
        'Radio'=>10,
        'Checkbox'=>11,
        'UploadImg'=>14,
        'UploadFile'=>13,
        'Select'=>12,
        'Editor'=>15,
        'Textarea'=>16,
        'Text'=>17,
        'Input'=>1,
        'Uk'=>2,
    ];

    //变量格式
    public const FORM_FIELD_FORMAT = [
        1=>'All',
        2=>'All',
        3=>'yyyy‐MM‐dd',
        5=>'yyyy‐MM‐dd H:i:s',
        6=>'int',
        7=>'0.0',
        8=>'0.00',
        9=>'0.000',
        10=>'NA',
        11=>'NA',
        12=>'NA',
        13=>'UPLOAD',
        14=>'UPLOAD',
        15=>'EDITOR',
    ];

    //控件类型
    public const FORM_FIELD_CONTROL_TYPE = [
        1=>'TextBox',
        2=>'TextBox',
        3=>'LabelBox',
        5=>'LabelBox',
        6=>'LabelBox',
        7=>'LabelBox',
        8=>'LabelBox',
        9=>'LabelBox',
        10=>'RadioList',
        11=>'CheckboxList',
        12=>'RadioList',
        13=>'UPLOAD',
        14=>'UPLOAD',
        15=>'EDITOR',
    ];

    //表单类型
    public const FORM_TYPE = [
        1=>'试验总结类',
        2=>'随机分组',
        3=>'SAE类',
        4=>'贯穿全程类',
        5=>'AE类',
        6=>'常规类',
        7=>'检查类（OCR识别）',
    ];

    public const variableHeader = ['变量名称','变量标签','变量类型','变量格式','控件类型','数据来源','域变量名','域变量标签','主题','行索引','受控术语','默认值','强制必填','是否只读','是否隐藏','是否需要Coding','是否需要SDV','是否需要DM Review','是否需要Medical Review','是否需要Safety Review','Tab键顺序','填写指南','问题描述'];

    public $Basicinformation = 'Readonly';


    /**
     * Notes : Execute
     * @param $data
     * @return bool
     * Author:唐伯虎不虎
     * Date:2023/2/23 10:00
     */
    public function execute($data)
    {
        $this->randomAlias = $this->LocalService()->itemFormField->getOneFieldVal('showfiled_name',"item_id = ".$data['item_id']." and is_del = 0 and var_name in ('RANDOM_GROUP_SYSTEM','RANGCA','RANDOM_GROUP_CUSTOM','RANGC')");
        //导出类型 1、完整空白  2、完整注释  3、数据库结构说明
        switch($data['export_type']){
            case $data['export_type'] == 1 || $data['export_type'] == 2:
                $this->fullblank($data);
                break;
            case $data['export_type'] == 3:
                $this->Structuredescription($data);
                break;
            case $data['export_type'] == 4:
                $this->fullblank($data);
                break;
            case $data['export_type'] == 5:
                $this->fullblank($data);
                break;
        }
        return true;
    }

    //获取项目申办方以及中心名称
    public function getsignatoryName($itemsignatoryDatas)
    {
        $back = [];
        foreach($itemsignatoryDatas as $k=>$v){
            if(!empty($v['is_teamleader'])){
                $back['teamleader_signatoryName'] = $v;
            }else{
                $arr['number'] = $v['number'];
                $arr['name'] = $v['label'];
                $arr['varname'] = $v['varname'];
                $back['signatoryName'][] = $arr;
            }
            $back['sign_list'][$v['value']] = $v['number'];
            $back['sign_varname'][$v['value']] = $v['varname'];
        }
        return $back;
    }



    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 getformfield($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', 'name', 'type','var_name','order','parent','form_id','unit'];
        $whereArr['order'] = 'order';
        $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);
        $fieldDatas = [];
        foreach($formfieldData as $k=>$v){
            
            $fieldDatas[$v['id']] = $v;
        }

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

        $whereArr['columns'] = ['id', 'name', 'type','var_name','order','parent','form_id','unit'];
        $whereArr['order'] = 'order';
        $formfieldAllData = $this->LocalService()->itemFormField->fetchAll($whereArr);
        $fieldAllDatas = [];
        foreach($formfieldAllData as $k=>$v){
            $fieldAllDatas[$v['id']] = $v;
        }
        $formidStr = implode(',',array_unique(array_column($formfieldData,'form_id')));
        $radiowhereArr['where'] = [
            'form_id' => StringHelper::toArray($formidStr),
        ];
        $radiowhereArr['columns'] = ['id','field_id','value','relation_information','score','is_score'];
        $radioDatas = $this->LocalService()->itemFormFieldRadio->fetchAll($radiowhereArr);

        $field_radio = [];
        $radio = [];
        foreach($radioDatas as $k=>$v){
            $radio[$v['relation_information']][] = $v;
            $field_radio[$v['field_id']]['value'] = $v['value'];
            $field_radio[$v['field_id']]['is_score'] = $v['is_score'];
            $field_radio[$v['field_id']]['score'] = $v['score'];
        }

        //查询表单字段隶属关系
        if($form_ids != 0) {
            $VersionwhereArr['where'] = [
                'form_id' =>StringHelper::toArray($form_ids),
            ];
        }else{
            $formId = $this->LocalService()->itemForm->fetchCol('id',[
                'is_del' => 0,
                'item_id' => $item_id,
            ]);

            $VersionwhereArr['where']['form_id'] = $formId;
        }
        $VersionwhereArr['columns'] = ['id', 'form_id', 'field'];
        $formversionData = $this->LocalService()->itemFormVersion->fetchAll($VersionwhereArr);
        $delfield = [];
        $common = [];
        $parentArr = [];
        $par = [];
        foreach($formversionData as $k=>$v){
            $result = json_decode($v['field'],'true');
            foreach($result as $key=>$value){
                if(!empty($value['children'])){
                    foreach($value['children'] as $kc=>$vc){
                        if(!empty($vc['relation_information'])){
                            foreach($vc['relation_information'] as $kri=>$vri){
                                if($vri==0)continue;
                                if($value['type'] == 10){

                                    if(isset($par[$value['id']]) && $par[$value['id']] != $vc['value']){
                                        $par[$vri] = $par[$value['id']].'-'.$vc['value'];
                                    }else{
                                        $par[$vri] = $vc['value'];
                                    }
                                }
                                $parentArr[$vri][] = $value['id'];
                            }
                        }
                    }
                }
                if(!empty($value['children']) && !isset($value['parent'])){
                    $relations = $this->handledata($result,$value);

                    $ralationformID = explode(',',$relations);
                    $common[$value['id']] = $ralationformID;
                }
                if(!empty($value['parent'])){
                    $delfield[] = $value['id'];
                }
            }
        }

        $newDatas = [];
        foreach($formfieldData as $k=>$v){
            $newDatas[] = $v;
            if(isset($common[$v['id']])){
                $commonKey = 0;
                foreach($common[$v['id']] as $kk=>$vv){
                    if(empty($vv)) continue;

                    if($fieldDatas[$v['id']]['type'] == 11){
                        $fieldDatas[$vv]['patents'] = $v['id'].'-'.$radio[$vv][$commonKey]['value'];
                        $fieldDatas[$vv]['name'] = $fieldAllDatas[$vv]['name'].'('.$fieldAllDatas[$radio[$vv][$commonKey]['field_id']]['name'].')';
                    }elseif($fieldDatas[$v['id']]['type'] == 10){
                        $parentKey = $this->LocalService()->itemExport->distinguish($parentArr,$vv,$v['id']);

                        $suffix = '';
                        if(isset($par[$vv])){
                            $suffix = '-'.$par[$vv];
                        }
                        if(!empty($parentKey)){
                            $fieldDatas[$vv]['patents'] = str_ireplace(',','-',$parentKey).$suffix;
                        }else{
                            $fieldDatas[$vv]['patents'] = $v['id'].$suffix;
                        }
                    }else{
                        $parentKey = $this->LocalService()->itemExport->getParentKey($parentArr,$vv,$v['id']);
                        if(!empty($parentKey)){
                            $fieldDatas[$vv]['patents'] = str_ireplace(',','-',$parentKey);
                        }else{
                            $fieldDatas[$vv]['patents'] = $v['id'];
                        }
                    }
                    ++$commonKey;
                    $newDatas[] = $fieldDatas[$vv];
                }
            }
        }

        $backArr = [];

        foreach($newDatas as $key=>$value){
            if(empty($value['form_id'])) continue;
            if(in_array($value['id'],$delfield) && !isset($value['patents'])) continue;

            $dataArr = [];
            $dataArr['id'] = $value['id'];
            $dataArr['type'] = $value['type'];
            $dataArr['var_name'] = $value['var_name'];
            $dataArr['name'] = $value['name'];
            $dataArr['unit'] = $value['unit'];
            if(in_array($value['type'],['10','11','12'])){
                $whereArr['where'] = "is_del = 0 and parent = ".$value['id'];
                $whereArr['columns'] = ['id', 'name','var_name'];
                $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);
                foreach($formfieldData as $optionk=>$optionv){
                    $formfieldData[$optionk]['value'] = $field_radio[$optionv['id']]['value'];
                    $formfieldData[$optionk]['score'] = $field_radio[$optionv['id']]['score'];
                    $formfieldData[$optionk]['is_score'] = $field_radio[$optionv['id']]['is_score'];
                }
                $dataArr['options'] = $formfieldData;
            }
            if(!empty($value['patents'])){
                $dataArr['patents'] = $value['patents'];
            }
            $backArr[$value['form_id']][] = $dataArr;
        }
//        var_dump($backArr);die;
        return $backArr;
    }

    //检查点  检查点对应的表单
    public function getItemchecktime($item_id)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($this->checktime_ids)) $whereArr['where']['id'] = StringHelper::toArray($this->checktime_ids);
        $whereArr['columns'] = ['id', 'check_name', 'stage_id','order'=>'check_order','is_del','is_copy','var_name'];
        $whereArr['order'] = 'check_order';
        $data = $this->LocalService()->itemChecktime->fetchAll($whereArr);
        //查询checkcontent
        $contentwhereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if(!empty($this->checktime_ids)) $contentwhereArr['where']['check_id'] = StringHelper::toArray($this->checktime_ids);
        $contentwhereArr['columns'] = ['id', 'check_id','form_id'];
        $contentwhereArr['order'] = 'order';
        $checkcontentDatas = $this->LocalService()->itemCheckcontent->fetchAll($contentwhereArr);
        $check = [];
        foreach($checkcontentDatas as $k=>$v){
            //跳过已删除的表单
            if(!isset($this->form[$v['form_id']])) continue;
            //跳过贯穿全程类表单
            if($this->form[$v['form_id']]['group_id'] == 4) continue;
            $v['checklist_id'] = $this->form[$v['form_id']]['checklist_id'];
            $check[$v['check_id']][] = $v;
        }

        $checktimeDatas = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {;
                $v['content'] = $check[$v['id']];
                $checktimeDatas[] = $v;
            }
        }
        return $checktimeDatas;
    }

    /**
     * Notes : 获取项目设置的检查项
     * @param int $item_id
     * @return array
     * Author:唐伯虎不虎
     * Date:2023/3/22 13:34
     */
    public function getOcrcheckdata(int $item_id)
    {
        $ocrWhere['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        $ocrWhere['columns'] = ['id','name','variable','category_id','unit','checkname_id'];
        $ocrDatas = $this->LocalService()->itemCheckname->fetchAll($ocrWhere);
        if(empty($ocrDatas)) return $ocrDatas;
        $checknameDatas = [];
        foreach($ocrDatas as $k=>$v){
            $checknameDatas[$v['category_id']][] = $v;
        }
        return $checknameDatas;
    }

    /**
     * Notes : 获取项目表单
     * @param int $item_id
     * @param int $form_id
     * @return array
     * Author:唐伯虎不虎
     * Date:2023/3/22 13:32
     */
    public function getform(int $item_id,int $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', 'var_name','rdg_type','group_id','checklist_id','order','is_field_score'];
        $whereArr['order'] = 'order';
        $data = $this->LocalService()->itemForm->fetchAll($whereArr);

        //查询表单是否有关联关系
        $formrelationwhereArr['columns'] = ['id', 'form_id'];
        $formrelationwhereArr['where'] = [
            'is_del' => 0,
            'form_id' => array_column($data,'id'),
        ];
        $formrelationdata = $this->LocalService()->itemFormRelation->fetchAll($formrelationwhereArr);

        //有关联关系的表单
        $relationDatas = array_column($formrelationdata,'form_id');

        $formdata = [];
        if (!empty($data)) {
            foreach ($data as $k => $v) {
                $formdata[$v['id']] = $v;
            }
        }
        if(!empty($relationDatas)){
            $radioWhere['where'] = [
                'form_id' => $relationDatas,
                new Operator('relation_information', Operator::OP_GT, 0),
            ];
            $radioWhere['columns'] = ['relation_information','form_id','value','field_id'];
            $associated = $this->LocalService()->itemFormFieldRadio->fetchAll($radioWhere);

            foreach($associated as $k=>$v){
                $formdata[$v['relation_information']]['associated'] = 1;
                $formdata[$v['relation_information']]['relationForm'] = $v['form_id'];
                $formdata[$v['relation_information']]['value'] = $v['value'];
                $formdata[$v['relation_information']]['field_id'] = $this->LocalService()->itemFormField->getOneFieldVal('parent',[
                    'is_del' => 0,
                    'id' => $v['field_id'],
                ]);
            }
        }
        return $formdata;
    }

    /**
     * Notes : 获取项目下阶段
     * @param int $item_id
     * @return mixed
     * Author:唐伯虎不虎
     * Date:2023/3/22 13:31
     */
    public function _getstageData(int $item_id)
    {
        return $this->LocalService()->itemResearchstage->fetchCol('stage_name',[
            'is_del' => 0,
            'item_id' => $item_id,
        ]);
    }

    /**
     * Notes : 获取受试者信息
     * @param int $patient_id
     * @return mixed
     * Author:唐伯虎不虎
     * Date:2023/3/22 13:30
     */
    public function getPatientinfo(int $patient_id){
        $wherePatientattr['where'] = [
            'is_del' => 0,
            'id' => $patient_id,
        ];
        $wherePatientattr['columns'] = ['id','item_id', 'itemsig_id', 'patient_number','patient_name','random_number','randgroup_id','random_id','patient_content','signatory_user_id'];
        $patientData = $this->LocalService()->patient->fetchOne($wherePatientattr);
        $patientarrtContent = json_decode($patientData['patient_content'],true);
        foreach($patientarrtContent as $k=>$v){
            $patientarrtContent[$v['id']] = $v;
            unset($patientarrtContent[$k]);
        }
        $arr = [];
        $arr[] = $patientData['patient_number'];
        $arr[] = $patientData['patient_name'];

        $patientData['patientinfo'] = implode('-',$arr);
        $patientData['content'] = $patientarrtContent;

        return $patientData;
    }

    //受试者拓展属性
    public function getpatientattrs(int $item_id){
        //拓展属性
        $data = $this->LocalService()->patientattrs->fetchAll(['where'=> [
            'item_id' => $item_id,
            'is_del' => 0,
            'is_hide' => 0,
        ],'columns'=>['id','attr_name','attr_field','attr_type','content']]);
        foreach($data as $k=>$v){
            if($v['attr_type'] == 3 || $v['attr_type'] == 4){
                //查询选项信息
                $select = json_decode($v['content'],true);
                foreach($select as $key=>$value){
                    $data[$k]['select'][$value['select_variable']] = $value['select_name'];
                }
            }
        }
        return $data;
    }


    /**
     * Notes : 受试者填写表单内容
     * @param $item_id
     * @param $patient_ids
     * @param $form_ids
     * @param $itemsig_ids
     * @return array
     * Author:唐伯虎不虎
     * Date:2023/3/22 14:15
     */
    public function getpatientform($item_id,$patient_ids,$form_ids,$itemsig_ids)
    {
        $patientformwhereArr['where'] = [
            'is_del' => 0,
            'item_id' => $item_id,
        ];
        if($patient_ids != 0) $patientformwhereArr['where']['patient_id'] = explode(',', $patient_ids);
        if($form_ids != 0) $patientformwhereArr['where']['form_id'] = explode(',', $form_ids);
        if($itemsig_ids != 0) $patientformwhereArr['where']['itemsig_id'] = explode(',', $itemsig_ids);
        $patientformwhereArr['columns'] = ['id','patient_id','form_id','checktime_id','data','itemsig_id','is_yc'];
        $patientformcontent = $this->LocalService()->patientFormContent->fetchAll($patientformwhereArr);
        $patientformDatas = [];

        if(!empty($patientformcontent)){
            foreach($patientformcontent as $k=>$v){
                $patientformDatas[$v['form_id']][$v['checktime_id']][] = $v;
            }
        }

        return $patientformDatas;
    }

    public function getformrules($item_id,$form_ids,$type){
        $whereArr['where'] = (new Where())->equalTo('is_del', 0)
                                          ->equalTo('item_id', $item_id)
                                          ->nest()
                                          ->equalTo('parent', 0)
                                          ->or
                                          ->isNull('parent')
                                          ->unnest();

        if($form_ids != 0) $whereArr['where']->in('form_id', explode(',', $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'] = explode(',', $form_ids);
        $formwhereArr['columns'] = ['id'];
        $formwhereArr['order'] = 'order';
        //表单ID
        $formDatas = $this->LocalService()->itemForm->fetchAll($formwhereArr);
        $data = [];
        //循环处理表单version
        foreach($formDatas as $key=>$value){
            $rule = $this->LocalService()->itemForm->getPreviewConfig($value['id']);
            $datas = $rule['form'];

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

                if(in_array($this->fieldType[$v['prop']]['type'],[17,18])) continue;
                $temporaryarr = [];
                $temporaryarr['id'] = $v['prop'];
                $temporaryarr['type'] = $this->fieldType[$v['prop']]['type'];
                $temporaryarr['unit'] = isset($v['unit']) ? $v['unit'] : '';
                $temporaryarr['var_name'] = $v['var_name'];
                $temporaryarr['name'] = $v['label'];
                $temporaryarr['name'] = $v['label'];
                if(isset($v['radios']) || isset($v['checkboxs'])){
                    $options = [];
                    if(!empty($v['radios'])){
                        foreach($v['radios'] as $optionk => $optionsV){
                            $options[$optionk]['name'] = $optionsV['label'];
                            $options[$optionk]['id'] = $optionsV['id'];
                            $options[$optionk]['value'] = $optionsV['value'];
                            $options[$optionk]['is_score'] = $optionsV['is_score'];
                            $options[$optionk]['score'] = $optionsV['score'];
                            $options[$optionk]['var_name'] = $optionsV['var_name'];
                        }
                    }

                    if(!empty($v['checkboxs'])){
                        foreach($v['checkboxs'] as $optionk => $optionsV){
                            $options[$optionk]['id'] = $optionsV['id'];
                            $options[$optionk]['name'] = $optionsV['label'];
                            $options[$optionk]['value'] = $optionsV['value'];
                            $options[$optionk]['is_score'] = $optionsV['is_score'];
                            $options[$optionk]['score'] = $optionsV['score'];
                            $options[$optionk]['var_name'] = $optionsV['var_name'];
                        }
                    }
                    if(!empty($options)) $temporaryarr['options'] = $options;
                }
                $data[$value['id']][] = $temporaryarr;
                if(($v['var_name'] == 'RANDOM_GROUP_SYSTEM' || $v['var_name'] == 'RANGCA' || $v['var_name'] == 'RANDOM_GROUP_CUSTOM' || $v['var_name'] == 'RANGC') && ($type == 1 || $type == 2)){
//                    if($blind_method == 0){
                        $data[$value['id']][99]['var_name'] = 'GRPID';
                        $data[$value['id']][99]['name'] = '方案分组';
//                    }
                    $data[$value['id']][100]['var_name'] = 'RANDID';
//                    $data[$value['id']][100]['name'] = '随机号';
                    $data[$value['id']][100]['name'] = $this->randomAlias;
                }


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

        }
        return $data;
    }

    public function handlefieldrules($rules,$id,$type)
    {
        $data = [];
        foreach($rules[$id] as $childK => $childV){

            foreach ($childV as $childfieldK => $childfieldV){
                $temporaryarr['id'] = explode("-", $childfieldV['prop'])[0];
                if(in_array($this->fieldType[$temporaryarr['id']]['type'])) continue;
                $temporaryarr['type'] = $this->fieldType[$temporaryarr['id']]['type'];
                if($temporaryarr['id'] != $childfieldV['prop']){
                    $par = explode('-',$childfieldV['prop']);
                    unset($par[0]);
                    $temporaryarr['patents'] = implode('-',$par);
                }
                if(isset($childfieldV['radios']) || isset($childfieldV['checkboxs'])){
                    $options = [];
                    if(!empty($childfieldV['radios'])){
                        foreach($childfieldV['radios'] as $optionk => $optionsV){
                            $options[$optionk]['id'] = $optionsV['id'];
                            $options[$optionk]['name'] = $optionsV['label'];
                            $options[$optionk]['value'] = $optionsV['value'];
                            $options[$optionk]['is_score'] = $optionsV['is_score'];
                            $options[$optionk]['score'] = $optionsV['score'];
                            $options[$optionk]['var_name'] = $optionsV['var_name'];
                        }
                    }
                    if(!empty($childfieldV['checkboxs'])){
                        foreach($childfieldV['checkboxs'] as $optionk => $optionsV){
                            $options[$optionk]['id'] = $optionsV['id'];
                            $options[$optionk]['name'] = $optionsV['label'];
                            $options[$optionk]['value'] = $optionsV['value'];
                            $options[$optionk]['is_score'] = $optionsV['is_score'];
                            $options[$optionk]['score'] = $optionsV['score'];
                            $options[$optionk]['var_name'] = $optionsV['var_name'];
                        }
                    }

                    $temporaryarr['options'] = $options;
                }
                $temporaryarr['unit'] = isset($v['unit']) ? $v['unit'] : '';
                $temporaryarr['var_name'] = $childfieldV['var_name'];
                $temporaryarr['name'] = $childfieldV['label'];
                $data[] = $temporaryarr;
                if(($childfieldV['var_name'] == 'RANDOM_GROUP_SYSTEM' || $childfieldV['var_name'] == 'RANGCA' || $childfieldV['var_name'] == 'RANDOM_GROUP_CUSTOM' || $childfieldV['var_name'] == 'RANGC') && ($type == 1 || $type == 2)){
                    $data[99]['var_name'] = 'GRPID';
                    $data[100]['var_name'] = 'RANDID';
                    $data[99]['name'] = '方案分组';
//                    $data[100]['name'] = '随机号';
                    $data[100]['name'] = $this->randomAlias;
                }
                if(isset($rules[$childfieldV['prop']])){
                    //单选/多选 有两层
                    $arr = $this->handlefieldrules($rules,$childfieldV['prop'],$type);
                    $data = array_merge($data,$arr);
                }
            }
        }
        return $data;
    }

    public function fullblank($data)
    {
        //受试者签名图片需要拼接
        $this->is_applets = $data['is_applets'];
        $this->version = $data['version'];
        $this->version_time = $data['version_time'];
        $this->checktime_ids = $data['checktime_ids'] ?: 0;
        $this->itemsig_ids = $data['itemsig_ids'] ?: 0;
        $this->export_type = $data['export_type'] ?: 0;

        $item_id = $data['item_id'];
        //项目名称
        $this->item_name = $this->LocalService()->itemInfo->getOneFieldVal('name',[
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称
        //项目编号
        $this->item_number = $this->LocalService()->itemInfo->getOneFieldVal('number',[
            'is_del' => 0,
            'id' => $item_id,
        ]);//获取项目名称
        //中心及申办方名称
        $itemsignatoryDatas = $this->LocalService()->itemSignatory->itemSigninfo($this->itemsig_ids, $item_id,0);

        //中心信息
        $this->signatoryName = $this->getsignatoryName($itemsignatoryDatas);

        //获取当前项目表单
        $this->form = $this->getform($item_id,0);

        $formfieldDatas = $this->getformrules($item_id,0,$data['export_type']);

        //查询检查项分类设置的指标
        $checknameDatas = $this->getOcrcheckdata($item_id);

        //查询检查点
        $checkDatas = $data['export_type'] != 5 ? $this->getItemchecktime($item_id) : [];

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

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

        //获取受试者拓展属性
        $this->patientattrs = $this->getpatientattrs($item_id);

        $this->export_type = $data['export_type'];

        if($data['export_type'] == 2 || $data['export_type'] == 5) $this->notes = true;

        if($data['export_type'] == 4){

            $patientArr = explode(',',$data['patient_id']);
            if(count($patientArr) >= 2){
                foreach($patientArr as $key=>$value){
                    $this->patientInfo = $this->getPatientinfo($value);
                    $this->pdf($checkDatas,$checknameDatas,$formfieldDatas,$data['create_time'],$item_id,1);
                }
                $this->compress($item_id,date('Y-m-d:H:i:s',$data['create_time']));

            }else{
                //获取受试者信息
                $this->patientInfo = $this->getPatientinfo($data['patient_id']);
                $this->pdf($checkDatas,$checknameDatas,$formfieldDatas,$data['create_time'],$item_id,0);
            }
        }else{
            $this->pdf($checkDatas,$checknameDatas,$formfieldDatas,$data['create_time'],$item_id,0);
        }
    }

    public function pdf($checkDatas,$checknameDatas,$formfieldDatas,$create_time,$item_id,$isuse_zipmode){
        //$isuse_zipmode  0 禁用压缩模式   1启动压缩模式
        // 创建新的PDF文档
        $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, 'A4', true, 'UTF-8', false);
        // 设置文档信息
        $pdf->SetCreator("创建者");
        $pdf->SetAuthor('作者');
        $pdf->SetTitle('标题');
        $pdf->SetSubject('项目名');
        $pdf->SetKeywords('关键字');
        //关闭头输出
        $pdf->setPrintHeader(false);
        //关闭尾输出
        $pdf->setPrintFooter(false);
        // 设置默认单间距字体
        $pdf->SetDefaultMonospacedFont('courier');
        // 设置自动分页符
        $pdf->SetAutoPageBreak(TRUE, 5);
        // 设置图像比例因子
        $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
        // 设置首页字体
        $pdf->SetFont('stsongstdlight', '', 12);
        //首页内容
        $pdf->AddPage();
        $pdf->Bookmark('封面页', 0, 0, '', 'B');
        //设置行高
        $pdf->Ln(1.07);
        //设置边距
        $pdf->setCellPaddings(5, 2.44, 5, 0);
        //首页内容
        $html = $this->firstpage($this->notes);

        //首页内容写入PDF
        $pdf->writeHTML($html, true, false, true, false, '');
        //设置主体内容字体
        $pdf->SetFont('stsongstdlight', '', 9);

        $tableCount = round(count($this->patientattrs)/10);

        $pdf->AddPage();
        $pdf->Bookmark('受试者拓展属性', 0, 0, '', 'B');
        for ($i=0;$i<$tableCount;$i++){

            $subset = array_slice($this->patientattrs, $i*10, 10);
            //受试者属性
            $patientAttrHtml = $this->patientattr($subset);

            $pdf->writeHTML($patientAttrHtml, true, false, true, false, '');
        }

        $patientformDatas = [];

        //受试者信息
        $patientInfo = $this->patientInfo;

        //表单数据
        $form = $this->form;

        //受试者完成数据---获取受试者信息
        if(!empty($patientInfo)){
            //获取受试者填写表单数据
            $patientformDatas = $this->getpatientform($patientInfo['item_id'],$patientInfo['id'],0,$patientInfo['itemsig_id']);

            //获取化验单缓存数据
            $laboratorytestreport = $this->_getlaboratory();
        }

        //头部表格中心编号、受试者编号、受试者姓名 【只有受试者完整注释时使用】
        $patientNumber = $patientInfo['patient_number'] ?: '';
        $patientName = $patientInfo['patient_name'] ?: '';
        $signatoryNumber = $this->signatoryName['sign_list'][$patientInfo['itemsig_id']] ?: '';

        //AE、SAE、贯穿全程类数据在PDF尾部输出
        $addcheck = [];
        foreach($form as $k=>$v){
            if($v['group_id'] == 3 || $v['group_id'] == 5 || $v['group_id'] == 4 || $v['group_id'] == 1){
                if(empty($addcheck)){
                    $arr['id'] = '000';
                    $addcheck[] = $arr;
                    $contentarr['check_id'] = 000;
                    $contentarr['form_id'] = $v['id'];
                    $contentarr['checklist_id'] = 0;
                    $addcheck[0]['content'][] = $contentarr;
                }else{
                    $contentarr['check_id'] = 000;
                    $contentarr['form_id'] = $v['id'];
                    $contentarr['checklist_id'] = 0;
                    $addcheck[0]['content'][] = $contentarr;
                }
            }
        }
        $checkDatas[999] = $addcheck[0];


        if($this->notes){
            //获取化验单分类的变量
            $checkcategoryWhere = [
                'is_del' => 0,
                'id' => array_unique(array_column($form,'checklist_id')),
            ];
            $checkcategory = $this->LocalService()->DictionaryCheckcategory->fetchCol('category_variable',$checkcategoryWhere);
        }
        $checkcategoryReportWhere['where'] = [
            'is_del' => 0,
            'id' => array_unique(array_column($form,'checklist_id')),
        ];
        $checkcategoryReportWhere['columns'] = ['id','report_type'];
        $checkcategoryReport = $this->LocalService()->DictionaryCheckcategory->fetchAll($checkcategoryReportWhere);
        $Report_type = [];
        foreach($checkcategoryReport as $k=>$v){
            $Report_type[$v['id']] = $v;
        }

        //查询项目是否设盲
        $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,
        ]);//获取项目名称

        $this->DateFormat = $this->LocalService()->itemCheckdate->getDateType($item_id);

        if($this->export_type == 5){
            foreach($form as  $value){
                //获取表单名称
                $form_name = $value['name'];

                $html = '';
                //获取表单类型  表单、化验单
                if(empty($value['checklist_id']) || $value['group_id'] == 10){
                    $result = $this->formatHandle($formfieldDatas[$value['id']],[],'',$blind_method);
                    $html .= $this->blank_formtable($result,$form_name,$value['var_name'],$formfieldDatas[$value['id']],$value['is_field_score']);
                }else{
                    //获取分类变量名
                    if($this->notes)$checkcategory_varname = $checkcategory[$value['checklist_id']] ?: '';
                    //化验单格式
                    $html .= $this->blank_checktable($checknameDatas[$value['checklist_id']],$form_name,$value['var_name'],$formfieldDatas[$value['id']],[],'',[],$checkcategory_varname,$Report_type[$value['checklist_id']]['report_type']);
                }
                $pdf->AddPage();
                $pdf->Bookmark($v['check_name'].' '.$form_name, 0, 0, '', 'B');
                $pdf->writeHTML($html, true, false, true, false, '');
            }
        }else{
            //处理表格
            foreach($checkDatas as $k=>$v){
//                if($v['id'] != 203068) continue;
                foreach($v['content'] as $key => $value){
//                    if($value['form_id'] != 93165) continue;
                    //获取表单名称
                    $form_name = $form[$value['form_id']]['name'];
                    //头部表格，目前只有检查点便连命是活的，其他都是默认的
                    $html = $this->blank_headerTable($signatoryNumber,$patientNumber,$patientName,$v['check_name'],$v['var_name']);
                    $html .='<p style="margin-top: 50px;"></p>';
                    //获取表单类型  表单、化验单
                    if(empty($value['checklist_id']) || $form[$value['form_id']]['group_id'] == 10){
                        if(!empty($patientInfo)){
                            //隶属关系判定是否展示
                            if(isset($form[$value['form_id']]['associated'])){

                                $form_id = $form[$value['form_id']]['relationForm'];

                                if($form[$value['form_id']]['group_id'] == 3){
                                    $patientformcontent = $patientformDatas[$form_id][0] ? : [];
                                }elseif($form[$value['form_id']]['group_id'] == 5){
                                    //不良事件
                                    $patientformcontentData = $this->LocalService()->itemExport->getpatientAeform($patientInfo['item_id'],$patientInfo['id'],$patientInfo['itemsig_id']);

                                    $relationformData = json_decode($patientformcontentData[$value['form_id']][0]['data'],true);
                                }else{
                                    $patientformcontent = $patientformDatas[$form_id][$v['id']] ? : [];
                                }
                                if($form[$value['form_id']]['group_id'] != 5 && !empty($patientformcontent)) $relationformData = json_decode($patientformcontent[0]['data'],true);

                            }
                            $patientformcontentData = [];
                            if($form[$value['form_id']]['group_id'] == 3){
                                $patientformcontent = $patientformDatas[$value['form_id']][0] ? : [];
                                if(!empty($patientformcontent)) $patientformcontentData[0] = $patientformcontent;
                            }elseif($form[$value['form_id']]['group_id'] == 5){
                                //不良事件
                                $patientformcontentData = $this->LocalService()->itemExport->getpatientAeform($patientInfo['item_id'],$patientInfo['id'],$patientInfo['itemsig_id']);
                            }else{
                                if($form[$value['form_id']]['group_id'] == 4 || $form[$value['form_id']]['group_id'] == 1){
                                    $patientformcontentData = $patientformDatas[$value['form_id']] ? : [];
                                }else{
                                    $patientformcontent = $patientformDatas[$value['form_id']][$v['id']] ? : [];
                                    if(!empty($patientformcontent)) $patientformcontentData[0] = $patientformcontent;
                                }
                            }
                            //贯穿全程类表单没有数据不导出
                            if(empty($patientformcontentData) && $form[$value['form_id']]['group_id'] == 4) continue;

                            $result = $this->formatHandle($formfieldDatas[$value['form_id']],$patientformcontentData,$v['id'],$blind_method);
                        }else{
                            $result = $this->formatHandle($formfieldDatas[$value['form_id']],[],$v['id'],$blind_method);
                        }

                        $html .= $this->blank_formtable($result,$form_name,$form[$value['form_id']]['var_name'],$formfieldDatas[$value['form_id']],$form[$value['form_id']]['is_field_score']);
                    }else{
                        if(!empty($patientInfo)){
                            $checkData = [];
                            if(!empty($laboratorytestreport[$v['id']][$value['form_id']])){
                                $checkData = $laboratorytestreport[$v['id']][$value['form_id']];
                                //判断是否是不检查
                            }
                            $html .= $this->blank_checktable($checknameDatas[$value['checklist_id']],$form_name,$form[$value['form_id']]['var_name'],$formfieldDatas[$value['form_id']],$checkData,$is_check = TRUE,$patientformDatas[$value['form_id']][$v['id']],'',$Report_type[$value['checklist_id']]['report_type']);
                        }else{
                            //获取分类变量名
                            if($this->notes)$checkcategory_varname = $checkcategory[$form[$value['form_id']]['checklist_id']] ?: '';
                            //化验单格式
                            $html .= $this->blank_checktable($checknameDatas[$value['checklist_id']],$form_name,$form[$value['form_id']]['var_name'],$formfieldDatas[$value['form_id']],[],'',[],$checkcategory_varname,$Report_type[$value['checklist_id']]['report_type']);
                        }
                    }
                    $pdf->AddPage();
                    $pdf->Bookmark($v['check_name'].' '.$form_name, 0, 0, '', 'B');
                    $pdf->writeHTML($html, true, false, true, false, '');
                }
            }
        }


//        $exportName = '';
        if($this->export_type ==4){
            $exportName = $signatoryNumber.'['.$patientNumber.']'.'-';
        }

        $exportName .= $this->exportType[$this->export_type];


//        if($this->notes){
//            $exportName = '完整注释';
//        }elseif(!$this->notes && empty($patientInfo)){
//            $exportName = '完整空白';
//        }else{
//            $exportName = $signatoryNumber.'['.$patientNumber.']'.'-受试者完整数据';
//        }
        $create_time = date('Y-m-d:H:i:s',$create_time);
        //保存PDF到本地
        $fileName = $this->item_name.'-'.$exportName.'-'.$create_time.'.pdf';
        $fileName = str_replace("/", '-', $fileName);
        ob_clean();

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

        //如果当前是压缩包模式  则创建文件夹，将所有受试者PDF放入文件夹中
        if($isuse_zipmode == 1){
            $path = APP_PATH . '/data/exportFile/'.$this->item_name.$create_time.'/';
            if(file_exists($path) == false)
            {
                mkdir($path, 0777, true);
            }
        }
        $res = $pdf->Output($path.$fileName, 'F');
        //============================================================+
        // END OF FILE
        //============================================================+
        return true;
    }


    //首页样式
    public function firstpage($notes)
    {
        $html = '<p style="font-size: 12px; letter-spacing: 1.07px;line-height: 2.44">项目名称：'.$this->item_name.'</p>';

        if(!empty($this->signatoryName['teamleader_signatoryName'])){
            $html .= '<p style="font-size: 12px;">申办方：'.$this->signatoryName['teamleader_signatoryName']['label'];
            if($notes && !empty($signatoryName['teamleader_signatoryName']['varname'])){
                $html .=  '<span style="background-color: #5bc0de;color: red;font-weight: bold;">&nbsp;&nbsp;{'.$this->signatoryName['teamleader_signatoryName']['varname']                                   .'}</span>';
            }
            $html .= '</p>';
        }

        $html .= '<p style="font-size: 13.5px;text-align:center;">eCRF</p>';
        $html .= '<p style="font-size: 10.5px;text-align:center;">eCRF版本号：'.$this->version.' 版本日期'.$this->version_time.'</p>';

        //配置首页中心信息
        if(!empty($this->signatoryName['signatoryName'])){
            foreach($this->signatoryName['signatoryName'] as $k=>$v){
                if($k == 0){
                    $html .= '<p style="font-size: 10.5px;text-align:center;">
                                中心：<input type="radio" name="1" checked>'.$v['number'].'&nbsp;'.$v['name'].'';
                    if($notes && !empty($v['varname'])){
                        $html .=  '<span style="background-color: #5bc0de;color: red;font-weight: bold;">&nbsp;&nbsp;{'.$v['varname'].'}</span>';
                    }
                    $html .= '</p>';
                }else{
                    $html .= '<p style="font-size: 10.5px;text-align:center;">
                        <input type="input" name="1" value="010239">'.$v['number'].'&nbsp;'.$v['name'].'';
                    if($notes && !empty($v['varname'])){
                        $html .=  '<span style="background-color: #5bc0de;color: red;font-weight: bold;">&nbsp;&nbsp;{'.$v['varname'].'}</span>';
                    }
                    $html .= '</p>';
                }
            }
        }
        return $html;
    }

    //受试者属性
    public function patientattr($subset){
        //受试者所有属性展示
        $html = '<h2 align="center">受试者属性</h2>';
        $html .= '
                    <style>
                        .table1 table {
                            border-right: 1px solid #000000;
                            border-bottom: 1px solid #000000;
                            width: 100%;
                        }
                    
                        .table1 th {
                            border-left: 1px solid #000000;
                            border-top: 1px solid #000000;
                            height: 30px;
                        }
                    
                        .table1 td {
                            border-left: 1px solid #000000;
                            border-top: 1px solid #000000;
                            height: 30px;
                        }
                    </style>
                    <table width="100%"  border="1" align="center" cellspacing="0" style="text-align:center;" class="table1">
                    <tr>';

        foreach($subset as $k=>$v){
            $html .= '<th>'.$v['attr_name'].'</th>';
        }
        $html.= '</tr>';

        $html .= '<tr>';
        //受试者拓展属性
        foreach($subset as $k=>$v){
            //只有导出受试者CRF才会处理受试者信息
            if($this->export_type == 4){
                if($v['attr_type'] == 3){
                    $html .= '<td>'.$this->patientattrs[$k]['select'][$this->patientInfo['content'][$v['id']]['value']];
                }elseif($v['attr_type'] == 4){
                    $option_content = '';
                    foreach($this->patientInfo['content'][$v['id']]['value'] as $selectK => $selectV){
                        $option_content .= '【'.$this->patientattrs[$k]['select'][$selectV].'】';
                    }
                    $html .= '<td>'.$option_content;
                }else{
                    $html .= '<td>'.$this->patientInfo['content'][$v['id']]['value'];
                }
            }else{
                $html .= '<td>';
            }
            if($this->notes){
                $html .= '<br><span style="background-color: #5bc0de;color: red">'.$v['attr_field'].'</span>';
                $html .= '<br><span class="type_style">Varchar(50)</span>';
            }
            $html .= '</td>';

        }
        $html.= '</tr>';
        $html .= '</table>';
        return $html;
    }

    //获取化验缓存数据
    public function _getlaboratory()
    {
        $patientInfo = $this->patientInfo;
        $path = APP_PATH . '/data/itemIdentificationResult/'.$patientInfo['item_id'].'/'.$patientInfo['itemsig_id'].'/' . $patientInfo['item_id'] . '-' . $patientInfo['itemsig_id'].'-'.$patientInfo['id'] . '.txt';
        if(file_exists($path) == false){
            return [];
        }else{
            return json_decode(file_get_contents($path, 0),true);
        }
    }

    //处理数据格式
    public function formatHandle($formfieldData,$content = [],$check_id,$blind_method)
    {
        //空格符
        $interval = '&nbsp;&nbsp;';

        //文本框
        $textBox = '______________';

        //单选框
        $checkbox = '〇';

        //单选框选中
        $checkbox_checked = '●';

        //文件
        $fielBox = '📕';

        $data = [];

        $lastTime = 0;

        $lastK = 0;
        if(!empty($content)){
            foreach($content as $key=>$value){
                foreach($value as $k=>$v){
                    if($check_id != 000 && isset($v['checktime_id']) && $v['checktime_id'] != $check_id){
                        unset($content[$key][$k]);
                        continue;
                    }
                }
            }
        }
        if(!empty($content)){
            foreach($content as $key=>$value){
                foreach($value as $kk=>$vv){
                    $patientformContent = json_decode($vv['data'],true);
                    $patientformContent = $this->handledatacharacteristic($patientformContent);
                    $fromscore = '';
                    foreach($formfieldData as $k=>$v){
                        $v['name'] = str_replace('>','＞',$v['name']);
                        $v['name'] = str_replace('<','＜ ',$v['name']);

                        if($v['var_name'] == 'RANDOM_GROUP_SYSTEM' || $v['var_name'] == 'RANGCA'){
                            $fieldName = '研究分层'.$interval;
                            $str = $fieldName.'<span style="background-color: yellow">'.$this->groupDatas[$this->patientInfo['randgroup_id']]."</span>";
                            ++$lastK;
                            $data[$lastK][] = $str;
                            if($blind_method == 0){
                                $fieldName = '随机分组'.$interval;
                                $str = $fieldName.'<span style="background-color: yellow">'.$this->randomDatas[$this->patientInfo['random_id']]."</span>";
                                ++$lastK;
                                $data[$lastK][] = $str;
                            }


                            $fieldName = '随机号'.$interval;
                            $str = $fieldName.'<span style="background-color: yellow">'.$this->patientInfo['random_number']."</span>";
                            ++$lastK;
                            $data[$lastK][] = $str;
                            continue;
                        }
                        if($v['var_name'] == 'RANDOM_GROUP_CUSTOM' || $v['var_name'] == 'RANGC'){
                            if($blind_method == 0){
                                $fieldName = '随机分组'.$interval;
                                $str = $fieldName.'<span style="background-color: yellow">'.$this->randomDatas[$this->patientInfo['random_id']]."</span>";
                                ++$lastK;
                                $data[$lastK][] = $str;
                            }


                            $fieldName = '随机号'.$interval;
                            $str = $fieldName.'<span style="background-color: yellow">'.$this->patientInfo['random_number']."</span>";
                            ++$lastK;
                            $data[$lastK][] = $str;
                            continue;
                        }



                        $resultKey = $v['id'];
                        if(isset($v['patents'])) {
                            //关联字段如果没有值则不展示
                            $relationValue = substr($v['patents'],strripos($v['patents'],"-")+1);
                            $relationKey = substr($v['patents'],0,strrpos($v['patents'],"-"));
                            if($patientformContent[$relationKey] != $relationValue) {
                                if(count($value) >=2 && count($formfieldData) == ($k+1) && ($kk+1) < count($value)){
                                    ++$lastK;
                                    $lastTime = 0;
                                    $data[$lastK][] = '';
                                    ++$lastK;
                                }
                                continue;
                            }
                            $resultKey .= '-'.$v['patents'];
                        }

                        if($v['type'] <10){
                            if(empty($v['unit'])){
                                $fieldName = $v['name'].$interval;
                            }else{
                                $fieldName = $v['name'].'&nbsp;'.'['.$v['unit'].']'.$interval;
                            }

                            if(!isset($patientformContent[$resultKey])) {
                                $str = $fieldName.'';
                                $unstrlenstr = $fieldName.'';
                            }else{
                                $str = $fieldName.'<span style="background-color: yellow">'.$patientformContent[$resultKey]."</span>";
                                $unstrlenstr = $fieldName.$patientformContent[$resultKey];
                            }

                        }elseif(in_array($v['type'],[10,11,12])){
                            if(empty($v['unit'])){
                                $fieldName = $v['name'].$interval;
                            }else{
                                $fieldName = $v['name'].'&nbsp;'.'['.$v['unit'].']'.$interval;
                            }
                            $is_score = false;
                            $score = '';
                            if(in_array($v['type'],[10,12])){
                                $optionStr = '';
                                $unstrlen = '';

                                foreach($v['options'] as $optionkey=>$optionvalue){
                                    $optionvalue['name'] = str_replace("<", '＜', $optionvalue['name']);
                                    if($optionvalue['value'] == $patientformContent[$resultKey]){
                                        if($optionvalue['is_score'] == 1){
                                            $is_score = true;
                                            $score += $optionvalue['score'];
                                            $fromscore += $optionvalue['score'];
                                        }
                                        $optionStr .= '<span style="color: #4cae4c;">'.$interval.$checkbox_checked.$optionvalue['name']."</span>";
                                    }else{
                                        $optionStr .= '<span>'.$interval.$checkbox.$optionvalue['name']."</span>";
                                    }
                                }
                            }else{
                                if(empty($v['unit'])){
                                    $fieldName = $v['name'].$interval;
                                }else{
                                    $fieldName = $v['name'].'&nbsp;'.'['.$v['unit'].']'.$interval;
                                }
                                if(!is_array($patientformContent[$resultKey])){
                                    $options = explode(',',$patientformContent[$resultKey]);
                                }else{
                                    $options = $patientformContent[$resultKey];
                                }
                                $optionStr = '';
                                $unstrlen = '';
                                foreach($v['options'] as $key=>$value){
                                    if(in_array($value['value'],$options)){
                                        if($value['is_score'] == 1){
                                            $is_score = true;
                                            $score += $value['score'];
                                            $fromscore += $value['score'];
                                        }
                                        $optionStr .= '<span style="color: #4cae4c">'.$interval.$checkbox_checked.$value['name']."</span>";
                                    }else{
                                        $optionStr .= $interval.$checkbox.$value['name'];
                                    }
                                }
                            }
                            if($is_score){
                                $str = $fieldName.'[共'.$score.'分]'.$optionStr;
                                $unstrlenstr = $fieldName.'[共'.$score.'分]'.$optionStr;
                            }else{
                                $str = $fieldName.$optionStr;
                                $unstrlenstr = $fieldName.$optionStr;
                            }
                        }else{
                            $str = $v['name'].$interval.$fielBox;
                        }
                        if(strlen(json_encode($unstrlenstr)) > 340){
                            ++$lastK;
                            $lastTime = 0;
                            $data[$lastK][] = $str;
                            ++$lastK;
                        }else{
                            if(($lastTime + strlen(json_encode($unstrlenstr))) < 340){
                                $data[$lastK][] = $str;
                                if($lastTime != 0) {
                                    ++$lastK;
                                    $lastTime = 0;
                                }else{
                                    $lastTime = strlen(json_encode($unstrlenstr));
                                }
                            }else{
                                ++$lastK;
                                $lastTime = strlen(json_encode($unstrlenstr));
                                $data[$lastK][] = $str;
                            }
                        }
                        //一对多表单中间要空一行
                        if(count($value) >=2 && count($formfieldData) == ($k+1) && ($kk+1) < count($value)){
                            ++$lastK;
                            $lastTime = 0;
                            $data[$lastK][] = '';
                            ++$lastK;
                        }
                    }
                    if(!empty($fromscore)){
                        $data[999] = $fromscore;
                    }
                }
            }
        }else{
            foreach($formfieldData as $k=>$v){
                $v['name'] = str_replace('>','＞',$v['name']);
                $v['name'] = str_replace('<','＜',$v['name']);
                if($v['type'] <10){
                    if(empty($v['unit'])){
                        $str = $v['name'].$interval.$textBox;
                    }else{
                        $str = $v['name'].'&nbsp;'.'['.$v['unit'].']'.$interval.$textBox;
                    }
                }elseif(in_array($v['type'],['10','11','12'])){
                    $optionStr = '';
                    foreach($v['options'] as $key=>$value){
                        $value['name'] = str_replace('>','＞',$value['name']);
                        $value['name'] = str_replace('<','＜',$value['name']);
                        $optionStr .= $interval.$checkbox.$value['name'];
                        if($value['is_score'] == true){
                            $optionStr .= '('.$value['score'].'分)';
                        }
                    }
                    if(empty($v['unit'])){
                        $str = $v['name'].$interval.$optionStr;
                    }else{
                        $str = $v['name'].'&nbsp;'.'['.$v['unit'].']'.$interval.$optionStr;
                    }
                }else{
                    $str = $v['name'].$interval.$fielBox;
                }


                if(strlen($str) > 120){
                    ++$lastK;
                    $data[$lastK][] = $str;
                }else{
                    if(($lastTime + strlen($str)) < 120 && count($data[$lastK]) != 2){
                        $data[$lastK][] = $str;
                        if($lastTime != 0) {
                            ++$lastK;
                            $lastTime = 0;
                        }else{
                            $lastTime = strlen($str);
                        }
                    }else{
                        ++$lastK;
                        $lastTime = 0;
                        $data[$lastK][] = $str;
                    }
                }
            }
        }
        return $data;
    }

    //头部表格
    public function blank_headerTable($signatoryNumber,$patientNumber,$patientName,$checkName,$varname)
    {
         $html = '
                    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head>
                    <body>
                    <style>
                        .table1 table {
                            border-right: 1px solid #000000;
                            border-bottom: 1px solid #000000;
                        }
                        
                        .table1 th {
                            border-left: 1px solid #000000;
                            border-top: 1px solid #000000;
                            height: 30px;
                        }
                        
                        .table1 td {
                            border-left: 1px solid #000000;
                            border-top: 1px solid #000000;
                            height: 30px;
                        }
                    </style>
                    <table width="100%"  border="1" align="center" cellspacing="0" style="text-align:center;" class="table1">
                    <tr>
                        <th>项目编号</th>
                        <th>中心编号</th>
                        <th>访视名称</th>
                    </tr>
                    <tr>
                        <td>'.$this->item_number;
                        if($this->notes){
                            $html .= '<br><span style="background-color: #5bc0de;color: red">STUDY</span>';
                            $html .= '<br><span class="type_style">Varchar(50)</span>';
                        }
                        $html .= '</td>

                        <td>'.$signatoryNumber;
                        if($this->notes){
                            $html .= '<br><span style="background-color: #5bc0de;color: red">INVSITE</span>';
                            $html .= '<br><span class="type_style">Varchar(50)</span>';
                        }
                        $html .= '</td>
                    
                        <td>'.$checkName;
                        if($this->notes){
                            if(!empty($varname)){
                                $html .= '<br><span style="background-color: #5bc0de;color: red">'.$varname.'</span>';
                            }
                            $html .= '<br><span class="type_style">Varchar(50)</span>';
                        }
                        $html .= '</td>

                    </tr>
                   </table>
                </body>';
         return $html;
    }

    //表单表格
    public function blank_formtable($result,$form_name,$var_name,$fieldDatas,$is_field_score)
    {
        $is_score = isset($result[999]) ? 1 : 0;
        $score = isset($result[999]) ? $result[999] : 0;
        $html = '
                <body>
                <style>
                    .table2 td {
                        border-left: 1px solid #000000;
                        border-top: 1px solid #000000;
                        font-size: 10.5px;
                        height: 30px;
                    }
                    .var_name{
                        font-size: 14px;
                        background-color: yellow;
                        font-weight: bold;
                    }
                </style>';
        if($this->notes){
            $html .= '<p><span class="var_name">Dataset:&nbsp;&nbsp;'.$var_name.'</span></p>';
        }

        $html.= '<table width="100%"  border="1"  cellspacing="0" style="margin-top: 30px;" class="table2">
                    <tr>
                        <th style="font-size: 26px; height: 50px;background-color: #ADADAD;text-align: center" colspan="2">'.$form_name.'</th>    
                    </tr>';

                    $i = 0;
                    $result = array_values($result);
                    $fieldDatas =  array_values($fieldDatas);
                    foreach($result as $kk => $vv){

                        if($kk == 999) continue;
                        if(count($result) == ($kk+1) && count($vv) == 1 && $is_field_score == 1){
                            $fieldVarname =  'SCORE_'.$var_name;
                            $fieldVarname .= '&nbsp; &nbsp;'.(exportpdf::FORM_FIELD_TYPE)[2];
                        }else{
                            $fieldVarname = $fieldDatas[$i]['var_name'];
                            $fieldVarname .= '&nbsp; &nbsp;'.(exportpdf::FORM_FIELD_TYPE)[$fieldDatas[$i]['type']];
                        }

                        if(count($vv) == 1){
                            $length = strlen(json_encode($vv[0]));

                            $height = 30+((floor($length/340))*10);

                            $height = $height.'px';

                            $html .= '<tr>  
                                        <td style="height: '.$height.'"  colspan="2">
                                            '.$vv[0];
                            if($this->notes){
                                $html .= '<br><span style="background-color: #5bc0de;color: red">'.$fieldVarname.'</span>';
                                $i++;
                            }
                            $html .= '</td></tr>';
                        }else{
                            $html .= '<tr>
                                        <td>'.$vv[0].'';
                            if($this->notes){
                                $html .= '<br><span style="background-color: #5bc0de;color: red">'.$fieldVarname.'</span>';
                            }
                            $html .= '</td>';
                            $html .= '<td>'.$vv[1].'';
                            if($this->notes){
                                ++$i;

                                if(count($result) == ($kk+1) && $is_field_score == 1){
                                    $fieldVarnameTwo =  'SCORE_'.$var_name;
                                    $fieldVarnameTwo .= '&nbsp; &nbsp;'.(exportpdf::FORM_FIELD_TYPE)[2];
                                }else{
                                    $fieldVarnameTwo = $fieldDatas[$i]['var_name'];
                                    $fieldVarnameTwo .= '&nbsp; &nbsp;'.(exportpdf::FORM_FIELD_TYPE)[$fieldDatas[$i]['type']];
                                }
//                                $fieldVarnameTwo = $fieldDatas[$i]['var_name'];
//                                $fieldVarnameTwo .= '&nbsp; &nbsp;'.(exportpdf::FORM_FIELD_TYPE)[$fieldDatas[$i]['type']];
                                $html .= '<br><span style="background-color: #5bc0de;color: red">'.$fieldVarnameTwo.'</span>';
                            }
                            $html .= '</td></tr>';

                            $i++;
                        }

                    }
        $html .= '
                  </table>';
                    if($this->notes && $is_field_score == 1){
                        $html .= '合计：________';
                        $html .= '<br><span style="background-color: #5bc0de;color: red">'.$fieldVarname.'</span>';
                    }elseif(!$this->notes && $is_field_score == 1 && $is_score != 1){
                        $html .= '合计：________';
                    }
                    if($is_score == 1){
                        $html .= '合计：'.$score.'分';
                    }
                  $html .= '</body>';
        return $html;
    }

    //化验单表格
    public function blank_checktable($result,$form_name,$var_name,$fieldDatas,$checkData = [],$is_check = FALSE,$formData = [],$checkcategory_varname = '',$report_type = 0)
    {
        $html = '
                 <body>
                 <style>
                    .table2 td {
                        border-left: 1px solid #000000;
                        border-top: 1px solid #000000;
                        font-size: 10.5px;
                        height: 30px;
                    }
                    .table2 th {
                        margin-left: 1px;;
                        font-size: 10.5px;
                        height: 30px;
                    }
                    .table_tr {
                        text-align: center;
                        padding-left: -10px;
                    }
                    .table_th {
                        text-align: center;
                        padding-left: -10px;
                        font-weight:bolder;
                    }
                    .var_name{
                        font-size: 14px;
                        background-color: yellow;
                        font-weight: bold;
                    }
                    .Variablename_style{
                        background-color: #5bc0de;color: red
                    }
                    .type_style{
                        background-color: yellowgreen;color: blue;
                    }
                    .var_name{
                        font-size: 14px;
                        background-color: yellow;
                        font-weight: bold;
                    }
                 </style>';
        if($this->notes){
            $html .= '<p><span class="var_name">Dataset:&nbsp;&nbsp;'.$var_name.'</span></p>';
        }

        $html .='<table width="100%"  border="1"  cellspacing="0" style="padding-left: 10px;" class="table2">
                     <tr>
                        <th style="font-size: 26px; height: 50px;background-color: #ADADAD;text-align: center" colspan="6">'.$form_name.'</th>    
                     </tr>
                     <tr>';
        if($is_check){
            $html .= '<td colspan="6">'.'是否进行'.$form_name.'检查？';
            if($is_check && !empty($formData)){
                $json_data = json_decode($formData[0]['data'],true);
                if($formData[0]['is_yc'] == 1){
                    //已开具
                    $html .= '<span class="var_name">&nbsp;&nbsp;√是</span>'.'&nbsp;&nbsp;√否，';
                }elseif($formData[0]['is_yc'] == 0){
                    //不检查
                    $html .= '>&nbsp;&nbsp;√是<span class="var_name">&nbsp;&nbsp;√否，</span>';
                }
//                210573
                if(isset($json_data[$fieldDatas[4]['id']])){
                    $html .= '请备注原因:&nbsp;'.'<span class="var_name">'.$json_data[$fieldDatas[4]['id']].'</span>';
                }else{
                    $html .= '请备注原因______________';
                }
            }else{
                $html .= '&nbsp;&nbsp;〇是&nbsp;&nbsp;〇否，&nbsp;请备注原因______________'.'';
            }
        }else{
            $html .= '<td colspan="6">'.'是否进行'.$form_name.'检查？&nbsp;&nbsp;〇是&nbsp;&nbsp;〇否，&nbsp;请备注原因______________'.'';
        }

        if($this->notes){
            $fieldVarname = $fieldDatas[0]['var_name'];
            $fieldVarname .= '&nbsp;,&nbsp;'.'<span class="type_style">'.(exportpdf::FORM_FIELD_TYPE)[$fieldDatas[0]['type']].'</span>';
            $fieldVarnameTwo = $fieldDatas[3]['var_name'];
            $fieldVarnameTwo .= '&nbsp;,&nbsp;'.'<span class="type_style">'.(exportpdf::FORM_FIELD_TYPE)[$fieldDatas[3]['type']].'</span>';
            $html .= '<br><span class = "Variablename_style"><span>'.$fieldVarname.'</span><span style="margin-left: 100px;">'.$fieldVarnameTwo                                     .'</span></span>';
        }
        //采集日期
        if($is_check && !empty($checkData)){
            $collect_date = '<span  style="color: #4cae4c">'.$checkData[0]['collect_date'].'</span>';

        }else{
            $collect_date = '______________';
        }


        $html .=     '</td>    
                     </tr> 
                     <tr>
                        <td colspan="6">'.'采集日期&nbsp;&nbsp;'.$collect_date.'';
        if($this->notes){
            $html .= '<br><span class = "Variablename_style">LBDAT_&nbsp;&nbsp;'.$checkcategory_varname.'</span>';
            $html .= '<span class = "type_style">Int</span>';
        }

        if($report_type == 0){
            $html .=    '</td> </tr>
                     <tr class="table_th"> 
                         <th style="width: 17%;">检查项目</th>
                         <th style="width: 15%;">测量结果</th>
                         <th style="width: 15%;">单位</th>
                         <th style="width: 30%;">范围值</th>';

            $html .= '<th style="width: 23%;">临床意义判定</th>
                    </tr>';
        }else{
            $html .=    '</td> </tr>
                     <tr class="table_th"> 
                         <th style="width: 30%;">检查项目</th>
                         <th style="width: 30%;">测量结果</th>';
            $html .= '<th style="width: 40%;">临床意义判定</th>
                    </tr>';
        }


                    foreach($result as $kk => $vv){

                        if(!$is_check){
                            $fieldVarname = $vv['variable'];
                            $html .= '
                                <tr style="height: 40px;" class="table_tr">
                                     <td>'.$vv['name'].'';
                            //指标名称
                            if($this->notes){
                                $html .= '<br><span class = "Variablename_style">LBTEST_'.$fieldVarname.'</span>';
                                $html .= '<br><span class = "type_style">Varchar(50)</span>';
                            }

                            $html .= '</td>
                                     <td>___________';
                            //测量结果
                            if($this->notes){
                                $html .= '<br><span class = "Variablename_style">LBORRES_'.$fieldVarname.'</span>';
                                $html .= '<br><span class = "type_style">Text</span>';
                            }

                            if($report_type == 0){
                                $html .= '</td>
                                     <td>'.$vv['unit'].'';
                                //单位
                                if($this->notes){
                                    $html .= '<br><span class = "Variablename_style">LBORRESU_'.$fieldVarname.'</span>';
                                    $html .= '<br><span class = "type_style">Varchar(30)</span>';
                                }


                                $html .= '</td>
                                     <td>'."上限:&nbsp;&nbsp;_________下限:&nbsp;&nbsp;_________".'';
                                //上限、下限
                                if($this->notes){
                                    $html .= '<br><span class = "Variablename_style">LBORNRHI_'.$fieldVarname.'<br>LBORNRLO_'.$fieldVarname.'</span>';
                                    $html .= '<br><span class = "type_style">Varchar(30)</span>';
                                }
                            }


                            $html .= '</td>
                                     <td><span>〇&nbsp;</span><span>〇&nbsp;</span><span>〇&nbsp;</span><span>〇&nbsp;</span>';
                            if($this->notes){
                                $html .= '<br><span class = "Variablename_style">LBCLSIG_'.$fieldVarname.'</span>';
                                $html .= '<br><span class = "type_style">Tinyint(1)</span>';
                            }
                            $html .= '</td>
                                </tr> ';
                        }else{
                            $flag = 0;

                            foreach($checkData as $key=>$value){
                                //替换 > <
                                $value['result'] = str_replace('>','＞',$value['result']);
                                $value['result'] = str_replace('<','＜ ',$value['result']);

                                $value['item_min_val'] = str_replace('>','＞',$value['item_min_val']);
                                $value['item_min_val'] = str_replace('<','＜ ',$value['item_min_val']);

                                $value['item_max_val'] = str_replace('>','＞',$value['item_max_val']);
                                $value['item_max_val'] = str_replace('<','＜ ',$value['item_max_val']);



                                if ($vv['checkname_id'] == $value['checkname_id']) {

                                    $flag = 1;

                                    $indexData['result'] = ($value['result'] != '') ? $value['result'] : '_____________';

                                    $indexData['unit'] = $value['unit'] ? trim($value['unit'],' ') : '______________';

                                    $indexData['min'] = $value['item_min_val'];

                                    $indexData['max'] = $value['item_max_val'];

                                    $indexData['normal_type'] = $this->clinicalevaluation($value['is_normal_type']) ? $this->clinicalevaluation($value['is_normal_type']) : $this->clinicalevaluation(0);
                                }
                            }

                            if($flag == 0){
                                $indexData['result'] = '_____________';
                                $indexData['unit'] = $vv['unit'] ? $vv['unit'] : '______________';
                                $indexData['min'] = $value['item_min_val'];
                                $indexData['max'] = $value['item_max_val'];
                                $indexData['normal_type'] = '______________';
                            }

                            $html .= '<tr style="height: 40px;" class="table_tr">';
                            $html .= '<td>'.$vv['name'].'</td>';
                            $html .= '<td>'.$indexData['result'].'</td>';
                            if($report_type == 0){
                                $html .= '<td>'.$indexData['unit'].'</td>';
                                $html .= '<td>'."上限:&nbsp;&nbsp;".$indexData["max"]."下限:&nbsp;&nbsp;".$indexData["min"]."".'</td>';
                            }
                            $html .= '<td>'.$indexData['normal_type'].'</td>';
                            $html .= '</tr> ';
                        }
                    }
                    $html .= '</table>';
                    $html .= '(※1.正常 2.异常有临床意义 3.异常无临床意义 4.未查)';
                    $html .= '</body>';
        return $html;
    }


    /**
     * Notes : 临床评估样式
     * @param $type
     * @return string
     * Author:唐伯虎不虎
     * Date:2023/2/24 17:22
     */
    public function clinicalevaluation($type){
        $style = '<i class="var_name" style="color: #4cae4c">√</i>';
        $unstyle = '<span>〇</span>';
        switch ($type){
            case 1:
                $str = ''.$style.'&nbsp;'.$unstyle.'&nbsp;'.$unstyle.'&nbsp;'.$unstyle.'';
                break;
            case 3:
                $str = ''.$unstyle.'&nbsp;'.$unstyle.'&nbsp;'.$style.'&nbsp;'.$unstyle.'';
                break;
            case 2:
                $str = ''.$unstyle.'&nbsp;'.$style.'&nbsp;'.$unstyle.'&nbsp;'.$unstyle.'';
                break;
            case 0:
                $str = ''.$unstyle.'&nbsp;'.$unstyle.'&nbsp;'.$unstyle.'&nbsp;'.$unstyle.'';
                break;
        }
        return $str;
    }


    /**
     * Notes : 处理数据含有“-”符号，截取符号前的ID
     * @param array $patientformContent
     * @return array
     * Author:唐伯虎不虎
     * Date:2023/2/24 10:22
     */
    public function handledatacharacteristic(array $patientformContent)
    {
        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;
            }
        }
        return $patientformContent;
    }

    /**
     * Notes :
     * @param $item_id
     * @return array
     * Author:唐伯虎不虎
     * Date:2023/2/21 10:07
     */
    public function getchoiceformfield(int $item_id)
    {
        $whereArr['where'] = [
            'is_del' => 0,
            'type' => 0,
            new Operator('parent', Operator::OP_GT, 0),
            'item_id' => $item_id,
        ];
        $whereArr['columns'] = ['id', 'name', 'type','var_name','order','parent','form_id'];
        $whereArr['order'] = 'order';
        $optionfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);

        $radiowhereArr['where'] = [
            'form_id' => array_unique(array_column($optionfieldData,'form_id')),
        ];
        $radiowhereArr['columns'] = ['id','field_id','value'];
        $radioDatas = $this->LocalService()->itemFormFieldRadio->fetchAll($radiowhereArr);
        $radio = [];
        foreach($radioDatas as $v){
            $radio[$v['field_id']] = $v;
        }

        $options = [];
        foreach($optionfieldData as $k=>$v){
            $v['value'] = $radio[$v['id']]['value'];
            $options[$v['parent']][] = $v;
        }
        $whereArr['where'] = [
            'is_del' => 0,
            'type' => [10, 11, 12],
            'item_id' => $item_id,
        ];
        $whereArr['columns'] = ['id', 'name', 'type','var_name','order','form_id'];
        $whereArr['order'] = 'order';
        $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);

        $formChoice = [];
        foreach($formfieldData as $k=>$v){
            $v['child'] = $options[$v['id']];
            $formChoice[$v['form_id']][] = $v;
        }
        return $formChoice;
    }

    public function getformcolumn($item_id)
    {
        $whereArr['where'] = (new Where())->equalTo('is_del', 0)
                                          ->equalTo('item_id', $item_id)
                                          ->nest()
                                          ->equalTo('parent', 0)
                                          ->or
                                          ->isNull('parent')
                                          ->unnest();

        $whereArr['columns'] = ['id', 'name', 'type','var_name','order','parent','form_id'];
        $whereArr['order'] = 'order';
        $formfieldData = $this->LocalService()->itemFormField->fetchAll($whereArr);

        $whereArr['where'] = (new Where())->equalTo('is_del', 0)
                                          ->equalTo('item_id', $item_id)
                                          ->like('rules', '%required%')
                                          ->nest()
                                          ->equalTo('parent', 0)
                                          ->or
                                          ->isNull('parent')
                                          ->unnest();
        $notrequiresDatas = $this->LocalService()->itemFormField->fetchCol('name', $whereArr['where']);


        $fieldDatas = [];
        foreach($formfieldData as $k=>$v){
            if(isset($notrequiresDatas[$v['id']])){
                $v['is_required'] = 1;
            }else{
                $v['is_required'] = 0;
            }
            $fieldDatas[$v['form_id']][] = $v;
        }
        return $fieldDatas;
    }


    /**
     * Notes : 设置文件名
     * @param string $fileName
     * @param string $sheetName
     * Author:唐伯虎不虎
     * Date:2023/2/22 11:49
     */
    public function setFileName(string $fileName = '', string $sheetName = 'Sheet1')
    {
        $fileName = empty($fileName) ? (string)time() : $fileName;

        $this->fileName = $fileName;

        $this->fileObject = $this->xlsxObject->fileName($fileName, $sheetName);

        $this->format = (new \Vtiful\Kernel\Format($this->fileObject->getHandle()));
    }

    /**
     * Notes : 设置头部样式
     * @return mixed
     * Author:唐伯虎不虎
     * Date:2023/2/22 11:51
     */
    public function setHeaderstyle()
    {
        return $this->format->align(Format::FORMAT_ALIGN_VERTICAL_CENTER)->bold()->toResource();
    }


    /**
     * Notes : 数据库结构说明
     * @param $data
     * @throws \Exception
     * Author:唐伯虎不虎
     * Date:2023/2/22 11:50
     */
    public function Structuredescription($data)
    {
        $create_time = $data['create_time'];

        $item_id = $data['item_id'];
        //获取当前项目表单
        $form = $this->getform($item_id,0);

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

        $create_time = date('Y-m-d:H:i:s',$create_time);

        $fileName = $item_name.'-数据库结构说明-'.$create_time.'.xlsx';

        $this->setFileName($fileName,'eCRF表单');

        //eCRF  sheet 1
        $Sheet1header = ['表单代码','表单名称','表单类型'];
        $sheet1Data = [];
        foreach($form as $k=>$v){
            $key = $k+1;
            $sheet1Data[$key][] = $v['var_name'];
            $sheet1Data[$key][] = $v['name'];

//            $sheet1Data[$key][] = $v['name'];
            $sheet1Data[$key][] = exportpdf::FORM_TYPE[$v['group_id']];
        }

        $this->fileObject->header($Sheet1header)->data($sheet1Data);
        $this->fileObject->setRow('A1:ZZ1', 20, $this->setHeaderstyle())->setColumn('A1:ZZ1', 20);
        //变量列表 sheet2

        $formField = $this->getformcolumn($item_id);
        if(!empty($formField)){
            $variableData = [];
            $variableHandle = [];
            $headerNumber = count(exportpdf::variableHeader);
            $i = 0;

            foreach($form as $formK=>$formV){
                if(!isset($formV['id'])) continue;
                $rule_handles = $this->LocalService()->itemForm->getPreviewConfig($formV['id'],true);

                $rule_handle = $rule_handles['config'];

                $is_score = 0;

                //查询表单是否为分值表单
                $scorefieldArr = $this->LocalService()->itemFormFieldRadio->fetchCol('field_id',[
                    'form_id' => $formV['id'],
                    'is_score' => 1,
                ]);
                if(!empty($scorefieldArr)){
                    $fieldidArr = $this->LocalService()->itemFormField->fetchCol('id',[
                        'id' => $scorefieldArr,
                        'is_del' => 0,
                    ]);
                    if(!empty($fieldidArr)){
                        //是分值表单，需要添加总分选项
                        $is_score = 1;
                    }
                }
                $joinnumber = $rule_handles['generateFields'];

                $joinnumberArr = [];
                foreach($joinnumber as $k=>$v){
                    $firstDash = strstr($v, '-', true);
                    $number = substr($v, 0, strlen($firstDash));
                    if(empty($number)) continue;
                    $joinnumberArr[$number] += 1;
                }

                $formnameInfo = $this->getformName($formV,false);
                $variableData[$i][] = '';
                $variableHandle[$i]['title'] =$formnameInfo;
                $variableHandle[$i]['start'] = $this->getColumn(0).($i+1);
                $variableHandle[$i]['end'] = $this->getColumn($headerNumber-1).($i+1);
                $variableHandle[$i]['background'] = '1';
                $variableHandle[$i]['merge'] = '1';
                ++$i;
                $variableHandle[$i]['start'] = $this->getColumn(0).($i+1);
                $variableHandle[$i]['end'] = $this->getColumn($headerNumber-1).($i+1);
                $variableHandle[$i]['background'] = '1';
                $variableData[$i] = exportpdf::variableHeader;
                ++$i;

                if(!isset($formField[$formV['id']])) continue;

                $k = 0;

                $result = $this->digui($rule_handle,$i,$k,'form','',$joinnumberArr);

                if($is_score == 1){
                    $result['variableData'][] = $this->scorearrhandle($formV['var_name']);
                }

                foreach($result['variableData'] as $kk=>$vv){
                    $variableData[$i] = $vv;
                    ++$i;
                }
            }

            $this->fileObject->addSheet('变量列表')->data($variableData);
            $this->queryMergeColumn($variableHandle);
            $this->fileObject->setRow('A1:ZZ1', 20, $this->setHeaderstyle())->setColumn('A1:ZZ1', 20);
        }

        //访视流程 sheet 3
        $visitProcess = [['访视阶段','访视编号','访视全程','是否允许计划外','访视时间段','表单代码','表单名称','表单顺序']];
        //查询检查点
        $checkDatas = $this->getItemchecktime($item_id);
        //访视阶段
        $stageDatas = $this->_getstageData($item_id);
        if(!empty($checkDatas)){
            $mergestartNumber = 2;
            $vistprocessKey = 1;
            $mergeData = [];
            $handle = [];
            foreach($checkDatas as $checkK => $checkV){
                foreach($checkV['content'] as $kk=>$vv){
                    $visitProcess[$vistprocessKey][] = $stageDatas[$checkV['stage_id']];
                    $visitProcess[$vistprocessKey][] = '';
                    $visitProcess[$vistprocessKey][] = $checkV['check_name'];
                    $visitProcess[$vistprocessKey][] = $checkV['is_copy'] ? '是' : '否';
                    $visitProcess[$vistprocessKey][] = '';
                    //表单
                    $visitProcess[$vistprocessKey][] = $form[$vv['form_id']]['var_name'];
                    $visitProcess[$vistprocessKey][] = $form[$vv['form_id']]['name'];
                    $visitProcess[$vistprocessKey][] = $form[$vv['form_id']]['order'];
                    $vistprocessKey++;
                }
                $contentNumber = count($checkV['content']);
                $mergeTitle = [$stageDatas[$checkV['stage_id']],'',$checkV['check_name'],$checkV['is_copy'] ? '是' : '否',''];

                for($i=0;$i<5;$i++){
                    $mergeData['start'] = $this->getColumn($i).$mergestartNumber;
                    $mergeData['end'] = $this->getColumn($i).($mergestartNumber+$contentNumber);
                    $mergeData['title'] = $mergeTitle[$i];
                    $mergeData['merge'] = 1;
                    $handle[] = $mergeData;
                }
                $mergestartNumber += $contentNumber+1;
            }
            $this->fileObject->addSheet('访视流程')->data($visitProcess);
            $this->queryMergeColumn($handle);
            $this->fileObject->setRow('A1:ZZ1', 20, $this->setHeaderstyle())->setColumn('A1:ZZ1', 20);
        }

        //受控术语 sheet 4
        $formchoice = $this->getchoiceformfield($item_id);
        if(!empty($formchoice)){
            $Controlledterm = [];
            $handle = [];
            $i = 0;
            foreach($form as $k=>$v)
            {
                if(!isset($formchoice[$v['id']])) continue;
                foreach($formchoice[$v['id']] as $optionsK => $optionsV){
                    $Controlledterm[$i][] = '';
                    $handle[$i]['title'] = $v['var_name'].'-'.$v['name'].','.$optionsV['name'].','.$optionsV['var_name'];
                    $handle[$i]['start'] = $this->getColumn(0).($i+1);
                    $handle[$i]['end'] = $this->getColumn(1).($i+1);
                    $handle[$i]['merge'] = '1';
                    $handle[$i]['background'] = '1';
                    $Controlledterm[$i][] = '';
                    ++$i;
                    $Controlledterm[$i][] = 'Code Value';
                    $Controlledterm[$i][] = 'Code Text';
                    $handle[$i]['start'] = $this->getColumn(0).($i+1);
                    $handle[$i]['end'] = $this->getColumn(1).($i+1);
                    $handle[$i]['background'] = '1';
                    ++$i;
                    foreach($optionsV['child'] as $option){
                        $Controlledterm[$i][] = $option['value'];
                        $Controlledterm[$i][] = $option['name'];
                        ++$i;
                    }
                    $Controlledterm[$i][] = '';
                    $Controlledterm[$i][] = '';
                    ++$i;
                }
            }
            $this->fileObject->addSheet('受控术语')->data($Controlledterm);

            $this->queryMergeColumn($handle);
            $this->fileObject->setRow('A1:ZZ1', 20, $this->setHeaderstyle())->setColumn('A1:ZZ1', 20);
        }
        //输出数据
        $filePath = $this->fileObject->output();

        //设置header头
        header("Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        header('Content-Disposition: attachment;filename="' . $fileName . '"');
        header('Content-Length: ' . filesize($filePath));
        header('Content-Transfer-Encoding: binary');
        header('Cache-Control: must-revalidate');
        header('Cache-Control: max-age=0');
        header('Pragma: public');
        ob_clean();
        flush();
    }


    public function digui($arr,$i,$k,$keyName,$var_name='',$join_number)
    {

        static $variableData = [];
        static $i;

        if($keyName == 'form') {
            $variableData = [];
        }

        if($keyName != 'form'){

            foreach($arr[$keyName] as $findK =>$findV){
                foreach($findV as $ks=>$v){

                    $convert = exportpdf::FORM_FIELD_convert[$v['type']];

                    $type = (isset($convert)) ? $convert : 1;

                    $firstDash = strstr($v['prop'], '-', true);
                    $number = substr($v['prop'], 0, strlen($firstDash));

                    if(empty($number) || $join_number[$number] == 1){
                        $variableData[$i][] = $v['var_name']; //变量名
                    }else{
                        $variableData[$i][] = $var_name.'_'.$v['var_name']; //变量名
                    }



                    $variableData[$i][] = $v['label']; //变量名称
                    $variableData[$i][] = exportpdf::FORM_FIELD_TYPE[$type]; //变量类型
                    $variableData[$i][] = exportpdf::FORM_FIELD_FORMAT[$type]; //变量格式
                    $variableData[$i][] = exportpdf::FORM_FIELD_CONTROL_TYPE[$type]; //变量格式
                    $variableData[$i][] = ''; //数据来源
                    $variableData[$i][] = ''; //域变量名
                    $variableData[$i][] = ''; //域变量标签
                    $variableData[$i][] = ''; //主题
                    $variableData[$i][] = ''; //行索引
                    $variableData[$i][] = $type == 10 ? 'TRUE' : 'FALSE'; //受控术语
                    $variableData[$i][] = ''; //默认值
                    $variableData[$i][] = $v['is_required'] == 1 ? 'TRUE' : 'FALSE'; //强制必填
                    $variableData[$i][] = 'False'; //是否只读
                    $variableData[$i][] = 'False'; //是否隐藏
                    $variableData[$i][] = 'False'; //是否需要Coding
                    $variableData[$i][] = 'False'; //是否需要SDV
                    $variableData[$i][] = 'False'; //是否需要DM Review
                    $variableData[$i][] = 'False'; //是否需要Medical Review
                    $variableData[$i][] = 'False'; //是否需要Safety Review
                    $variableData[$i][] = $k+1; //Tab键顺序
                    $variableData[$i][] = ''; //填写指南
                    $variableData[$i][] = ''; //问题描述
                    ++$i;
                    if(isset($arr[$v['prop']])){
                        $this->digui($arr,$i,$k,$v['prop'],$v['var_name'],$join_number);
                    }
                }
            }
        }else{
            foreach($arr[$keyName] as $ks=>$v){
                $convert = exportpdf::FORM_FIELD_convert[$v['type']];

                $type = (isset($convert)) ? $convert : 1;

                $variableData[$i][] = $v['var_name']; //变量名
                $variableData[$i][] = $v['label']; //变量名称
                $variableData[$i][] = exportpdf::FORM_FIELD_TYPE[$type]; //变量类型
                $variableData[$i][] = exportpdf::FORM_FIELD_FORMAT[$type]; //变量格式
                $variableData[$i][] = exportpdf::FORM_FIELD_CONTROL_TYPE[$type]; //变量格式
                $variableData[$i][] = ''; //数据来源
                $variableData[$i][] = ''; //域变量名
                $variableData[$i][] = ''; //域变量标签
                $variableData[$i][] = ''; //主题
                $variableData[$i][] = ''; //行索引
                $variableData[$i][] = $type == 10 ? 'TRUE' : 'FALSE'; //受控术语
                $variableData[$i][] = ''; //默认值
                $variableData[$i][] = $v['is_required'] == 1 ? 'TRUE' : 'FALSE'; //强制必填
                $variableData[$i][] = 'False'; //是否只读
                $variableData[$i][] = 'False'; //是否隐藏
                $variableData[$i][] = 'False'; //是否需要Coding
                $variableData[$i][] = 'False'; //是否需要SDV
                $variableData[$i][] = 'False'; //是否需要DM Review
                $variableData[$i][] = 'False'; //是否需要Medical Review
                $variableData[$i][] = 'False'; //是否需要Safety Review
                $variableData[$i][] = $k+1; //Tab键顺序
                $variableData[$i][] = ''; //填写指南
                $variableData[$i][] = ''; //问题描述
                ++$i;
                if(isset($arr[$v['prop']])){
                    $this->digui($arr,$i,$k,$v['prop'],$v['var_name'],$join_number);
                }
            }
        }

        $back['i'] = $i;
        $back['k'] = $k;
        $back['variableData'] = $variableData;
        return $back;
    }


    public function scorearrhandle($var_name)
    {
        $variableData[] = 'SCORE_'.$var_name;
        $variableData[] = '合计值'; //变量名称
        $variableData[] = exportpdf::FORM_FIELD_TYPE[6]; //变量类型
        $variableData[] = exportpdf::FORM_FIELD_FORMAT[6]; //变量格式
        $variableData[] = exportpdf::FORM_FIELD_CONTROL_TYPE[6]; //变量格式
        $variableData[] = ''; //数据来源
        $variableData[] = ''; //域变量名
        $variableData[] = ''; //域变量标签
        $variableData[] = ''; //主题
        $variableData[] = ''; //行索引
        $variableData[] = 6 == 10 ? 'TRUE' : 'FALSE'; //受控术语
        $variableData[] = ''; //默认值
        $variableData[] = FALSE; //强制必填
        $variableData[] = 'False'; //是否只读
        $variableData[] = 'False'; //是否隐藏
        $variableData[] = 'False'; //是否需要Coding
        $variableData[] = 'False'; //是否需要SDV
        $variableData[] = 'False'; //是否需要DM Review
        $variableData[] = 'False'; //是否需要Medical Review
        $variableData[] = 'False'; //是否需要Safety Review
        $variableData[] = 1; //Tab键顺序
        $variableData[] = ''; //填写指南
        $variableData[] = ''; //问题描述
        return $variableData;
    }

    public function handlearrray($arr)
    {
        foreach($arr as $key=>$value){
            foreach($value as $k=>$v){
                return $v;
            }
        }
    }

    /**
     * Notes : 合并单元格
     * @param array $colManage
     * Author:唐伯虎不虎
     * Date:2023/2/21 16:52
     */
    private function queryMergeColumn(array $colManage)
    {
        $backgroundStyle  = $this->format->background(\Vtiful\Kernel\Format::COLOR_SILVER)->border(\Vtiful\Kernel\Format::BORDER_THIN)->toResource();

        foreach ($colManage as $value) {

            if(isset($value['merge'])){
                $this->fileObject->mergeCells("{$value['start']}:{$value['end']}", $value['title']);
            }

            if(isset($value['background'])){
                $this->fileObject->setRow("{$value['start']}:{$value['end']}", 20,$backgroundStyle);
            }
        }
    }

    /**
     * Notes : 获取单元格列标识
     * @param int $num
     * @return mixed
     * Author:唐伯虎不虎
     * Date:2023/2/21 11:22
     */
    private function getColumn(int $num)
    {
        return $this->xlsxObject::stringFromColumnIndex($num);
    }

    /**
     * Notes : 处理表单（字段）名称
     * @param array $arr
     * @param bool $is_column
     * @return string
     * Author:唐伯虎不虎
     * Date:2023/2/22 11:37
     */
    private function getformName(array $arr,bool $is_column)
    {
        $str = [];
        if(!$is_column){
            $str[] = $arr['var_name'];
            $str[] = $arr['name'];
        }
        return implode('-',$str);
    }

    //查询上四/五代 锚点
    private $anchor = [];
    //常量
    const mo = 'mother';
    const fa = 'father';

    /**
     * Notes : 父级关系处理（所有数据未做排序）
     * Author: Wl
     * Date:2023/6/9 13:44
     */
    public function genealogy()
    {
        $exportpdfWhere['where'] = "user_info_id = 4275 and father !=0 and mother !=0";
        $exportpdfWhere['columns'] = ['son','father','mother','user_info_id'];
        $exportDatas = $this->LocalService()->itemExportpdf->fetchAll($exportpdfWhere);
        //子代最多的鸽子

        //上四代/上五代使用频率最高的鸽子 此方法
        //--------------以儿子为锚点向上找父亲
        $anchor = [];
        foreach($exportDatas as $k=>$v){
            $anchor[$v['son']][] = $v;
        }

        $this->anchor = $anchor;
var_dump($this->anchor);die;
        $frequency = []; //存储4代/5代数据
        foreach($exportDatas as $k=>$v){
            $vertex = $this->findgeneration($v['father'],5,1,exportpdf::fa);
            if(!empty($vertex)) $frequency[$vertex] += 1;
            $vertex = $this->findgeneration($v['mother'],5,1,exportpdf::mo);
            if(!empty($vertex)) $frequency[$vertex] += 1;
        }
        print_r($frequency);die;
    }

    /**
     * Notes : 递归处理
     * @param $parent_id 当前的父级ID（mather/mother）
     * @param int $level 向上几代
     * @param int $num 初始是第几代
     * @param $type 'mother'  'father'
     * ps:此方法也可以拓展找子代
     * @return int|mixed
     * Author:唐伯虎不虎
     * Date:2023/6/9 13:47
     */
    public function findgeneration($parent_id,$level=5,$num=1,$type)
    {
        if(isset($this->anchor[$parent_id])){
            if($num ==$level){
                return $this->anchor[$parent_id][0][$type];
            }
            return $this->findgeneration($this->anchor[$parent_id][0][$type],$level,$num+1,$type);
        }else{
            return 0;
        }
    }

    /**
     * Notes :压缩文件夹并下载
     * @param $item_id
     * @param $itemsig_id
     * @return false
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:11
     */
    public function compress(int $item_id,$create_time)
    {
        //项目名称
        $iteninfoWhere['where'] = "id = $item_id and is_del = 0";
        $iteninfoWhere['columns'] = ['name','number','fid'];
        $iteminfo = $this->LocalService()->itemInfo->fetchOne($iteninfoWhere);

        $path = APP_PATH . '/data/exportFile/'.$iteminfo['name'].$create_time;

        if(file_exists($path) == false) return false;


        $filename = APP_PATH . '/data/exportFile/'.$iteminfo['name'].$create_time.'-ZIP';

        //开始压缩文件并且下载到本地
        $res = $this->create_zip($path,$filename);
        //删除文件夹
        $this->DelDirHandle($path);

        return true;
    }

    /**
     * Notes :要压缩的文件夹路径/要生成的压缩包名称
     * @param $path
     * @param $filename
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:11
     */
    public function create_zip($path,$filename)
    {
        $zip = new \ZipArchive();
        if($zip->open($filename.'.zip', \ZipArchive::CREATE | \ZipArchive::OVERWRITE)) {
            $this->addFileToZip($path, $zip);//调用方法，对要打包的根目录进行操作，并将ZipArchive的对象传递给方法PHP 截取第二个/后数据
            $zip->close(); //关闭处理的zip文件
        }
    }

    /**
     * Notes :递归写入压缩包
     * @param $path
     * @param $zip
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:10
     */
    public function addFileToZip($path,$zip) {
        $handler = opendir($path); //打开当前文件夹由$path指定。

        while (($filename = readdir($handler)) !== false) {

            if ($filename != "." && $filename != "..") {
                //文件夹文件名字为'.'和‘..’，不要对他们进行操作

                if (is_dir($path . "/" . $filename)) {
                    $this->addFileToZip($path . "/" . $filename, $zip);
                } else {
//                    $mkpath = substr($path . "/" . $filename,strpos($path . "/" . $filename,'public')+7);
//                    var_dump($mkpath);die;
                    $url = $path . "/" . $filename;
                    $url = substr($url,stripos($url,"/")+1);
                    $filename_new = substr($url,stripos($url,"/")+1);
                    $absolutely = substr($filename_new,stripos($filename_new,"/")+1);
                    $absolutely = $this->handleaddress($absolutely);
                    $zip->addFile($path . "/" . $filename,$absolutely);
                }
            }
        }
        @closedir($path);
    }

    public function handleaddress($path)
    {
        $address = explode('/',$path);
        $absolutely = substr($path,stripos($path,"/")+1);
        if($address[0] != 'exportFile'){
//            $absolutely = substr($path,stripos($path,"/")+1);
            $absolutely = $this->handleaddress($absolutely);
        }
        return $absolutely;
    }

    /**
     * Notes :删除文件夹
     * @param $path
     * @return bool
     * Author:唐伯虎不虎
     * Date:2022/8/25 14:12
     */
    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;
    }

}
