<?php
namespace app\controller;

use app\model\CdssXyDisease;
use app\model\ClickCount;
use app\model\EsCollection;
use app\model\XyZskDisease;
use think\facade\Session;
use think\helper\Arr;
use think\response\Json;
use think\facade\Request;
use app\model\History;


/**
 * Es文献类（科研探索）
 */
class EsDocument extends CommonEsController
{

    /**
     * 测试方法
     */
    public function test()
    {
        $orderArray = [
            [
                'order_field' => 'mark',
                'order'       => 'desc'
            ] ,
            [
                'order_field' => 'year',
                'order'       => 'desc'
            ]
        ];
        return $this->_json_succ(
            $this->setOrderOther($orderArray)
        );
    }


    /**
     * 设置语言
     */
    public function setLanguage()
    {
        $language = Request::param('language') ?? 'document_zh';
        Session::set('language' , $language);
        return $this->_json_succ(
            [
                'language' => $language
            ]
        );
    }


    /**
     * 搜索提示
     */
    public function searchTip()
    {
        $search = Request::param('search') ?? '';
        if( ! $search) {
            return $this->_json_error('请求有误！');
        }

        $field = Request::param('field') ?? 'name';
        $diseases   = CdssXyDisease::field($field)
                ->where('name' , 'like' , "%$search%")
                ->select()
                ->toArray() ?? [];
        $diseaseArr = empty($diseases) ? [] : array_values(array_filter(array_column($diseases , $field)));

        return $this->_json_succ(
            $diseaseArr
        );
    }


    /**
     * 普通检索｜ 疾病别名
     */
    public function singleSearchRecommendDisease()
    {
        $keyword = Request::param('search') ?? '';
        if( ! $keyword) {
            return $this->_json_error(
                '请求参数有误！'
            );
        }
        $diseases = (new CdssXyDisease())->getNameAndAlias($keyword);
        return $this->_json_succ(
            $diseases
        );
    }



    /**
     * 高级检索推荐疾病 ｜ 疾病别名
     */
    public function searchRecommendDisease()
    {
        $keyword = Request::param('keyword') ?? '';
        if( ! $keyword) {
            return $this->_json_error('请求有误！');
        }
        $disease = CdssXyDisease::field('name , alias')->where('name' , $keyword)->find();
        if(empty($disease)) {
            $disease = CdssXyDisease::field('name , alias')->whereOr('alias' , 'like' ,"%$keyword%")->find();

        }
        $name   = $disease->name;
        $alias  = $disease->alias;
        if(stripos($alias , ';') !== false) {
            $newArray[] = $name;
            $aliasArr   = explode(';' , $alias);
            $newArray   = array_merge($newArray, $aliasArr);
        } elseif(stripos($alias , '；') !== false) {
            $newArray[] = $name;
            $aliasArr   = explode('；' , $alias);
            $newArray   = array_merge($newArray, $aliasArr);
        } else {
            $newArray[] = $name;
            $newArray[] = $alias;
        }

        $diseases    = CdssXyDisease::field('name')->whereOr('name' , 'like' ,"%$keyword%")->select()->toArray();
        $diseasesArr = array_column($diseases , 'name') ?? [];
        return $this->_json_succ(
            array_unique(array_merge($newArray, $diseasesArr))
        );
    }



    /**
     * 文献首页
     *
     * @param $document   string
     * @param $field      string
     * @param $page       int
     * @return Json
     */
    public function index():Json
    {
        $uid   = Request::param('uid')   ?? '833456167';
        $field = Request::param('field') ?? '*';
        $page  = Request::param('page')  ?? 1;
        $limit = ($page - 1) * $this->pagesize;
        //$index = $this->currentLanguage();
	$index = 'document_zh';
	$params =  [
            'index' => $index,
            'body'  => [
                'from'  => $limit,
                'size'  => $this->pagesize,
                'query' => [
                    'match_all'  => (object)[] ,      // 查询全部
                ],
                "_source" => $field,                  // 获取制定字段
               //"sort"    => $this->setOrderOther();
	    ],
	    "preference" => "_primary_first"
        ];
	//print_r($params);die;
        $result = $this->esCommonGetData($params);
        return $this->_json_succ(
            $this->dataAssemble(
                $uid , $result['total'] , $result['data']
            )
        );
    }


    /**
     * 文献详情
     */
    public function esDocumentDetail()
    {
        $periodicalMd5 = Request::param('periodical_md5') ?? '';
        $uniqId        = Request::param('uniq_id') ?? '';
        $pmid        = Request::param('PMID') ?? '';
        
	if( ! $periodicalMd5 && ! $uniqId && ! $pmid) {
            return $this->_json_error('请求参数有误！');
        }

        $index = 'document_en,document_zh';
        if($periodicalMd5 || ($periodicalMd5 && $uniqId)) {
            $field = 'periodical_md5';
            $value = $periodicalMd5;
        }

        if($uniqId && ! $periodicalMd5) {
            $field = 'uniq_id';
            $value = $uniqId;
        }

        if ($pmid && ! $uniqId) {
            $field = 'PMID';
            $value = $pmid;
        }

        $uid    = Request::param('uid') ?? '833456167';
        $params =  [
            'index' => $index,
            'body'  => [
                'query' => [
                    "constant_score" => [
                        "filter" => [
                            "term" => [
                                $field => $value
                            ]
                        ],
                    ],
                ],
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search($params);
        if( 0 == $result['hits']['total']) {
            return $this->_json_error('未查询到数据！');
        }

        $detail = $result['hits']['hits'][0]['_source'] ?? [];

        $detail['is_collection'] = EsCollection::checkIsCollection($uid , $value);
        $detail['click_count']   = ClickCount::where('md5' , $value)->value('click_count');

        $titleArr = [
            'N1站淋巴结检出数目对pT1～3N0M0非小细胞肺癌患者预后的影响' ,
            '滋燥养荣颗粒治疗非小细胞肺癌EGFRIs相关皮肤干燥症阴虚血燥证有效性及安全性的长期随访研究',
            '胸腔镜肺叶切除术与肺段切除术治疗T1bN0M0 期非小细胞肺癌的回顾性队列研究'
        ];
        //if(in_array($detail['title'] , $titleArr)) {
        //    $detail['pdf_url'] = 'https://jm.jiankangche.cn/zsk/pdf/202302082310.pdf';
        //} else {
        //    $detail['pdf_url'] = $this->checkDocPdfIsExist($detail['pdf_name'] ?? '');
        //}

$datail['pdf_url'] = '';

        ClickCount::docClickCount($value);

        return $this->_json_succ(
            $detail
        );
    }


    /**
     * 检测pdf文档地址是否可访问
     */
    private function checkDocPdfIsExist($pdf_name = '')
    {
        if( ! $pdf_name ) {
            return "";
        }
        $url   = 'https://jm.jiankangche.cn/zsk/pdf/'.$pdf_name;
        $check = get_headers($url);
        return stripos($check[0] , '200') !== false ? $url : "";
    }


    /**
     * 相关文献
     */
    public function getDocumentByTag()
    {
        $title = Request::param('title') ?? '';
        $tag   = Request::param('tag')   ?? 'similarity';
        $uid   = Request::param('uid')   ?? '833456167';
        if( ! $title || ! $tag ) {
            return $this->_json_error('请求错误！');
        }

        $page  = Request::param('page') ?? 1;
        $limit = ($page - 1) * $this->pagesize;

        $index  = $this->currentLanguage();
        $params = [
            'index' => $index,
            'body'  => [
                'size'  => $this->pagesize,
                'from'  => $limit,
                'query' => [
                    "match"=>[
                        'title' => [
                            'query' => $title,
                            'boost' => 3, // 权重
                        ],
                    ],
                ],
            ]
        ];

        $result = $this->esCommonGetData($params);
        return $this->_json_succ(
            $this->dataAssemble($uid , $result['total'] , $result['data'])
        );
    }


    /**
     * 参考文献
     */
    public function references()
    {
    }



    /**
     * 最高 ｜ 最新 期刊
     *
     * @param $tag    string 标识
     * @param $page   int    分页
     * @return Json
     */
    public function getAlbumByTag():Json
    {
        $tag   = Request::param('tag')   ?? 'highest';
        if( ! $tag) {
            return $this->_json_error('请求参数有误！');
        }

        /**
         * 最高
         */
        if('highest' === $tag) {
            $orderField = 'total_citations_number.keyword';
            $order      = 'desc';
        }

        /**
         * 最新
         */
        if('recently' === $tag) {
            $orderField = 'first_time.keyword';
            $order      = 'desc';
        }

        $page  = Request::param('page')  ?? 1;
        $limit = ($page - 1) * $this->pagesize;


        $index = $this->currentLanguage();
        $albumIndex = 'document_zh' === $index ? 'album' : 'album_en';
        $params =  [
            'index' => $albumIndex,
            'body'  => [
                'from'  => $limit,
                'size'  => $this->pagesize,
                'query' => [
                    'match_all'  => (object)[] ,        // 查询全部
                ],
                //"_source" => $field,                  // 获取制定字段
                "sort"  => $this->setOrder($orderField , $order),
            ],
        ];

        return $this->_json_succ(
            $this->esCommonGetData($params)
        );
    }



    /**
     * 搜索
     */
    public function conditionFilter()
    {
        $searchType = Request::param('search_type') ?? 'many';
        if( ! $searchType ) {
            $this->_json_error('参数请求错误！');
        }

        /**
         * 排序
         */
        $orderField = Request::param('order_field') ?? 'year';
        $order      = Request::param('order')       ?? 'desc';
        $searchTag  = Request::param('search_tag')  ?? 2;
        $uid        = Request::param('uid')         ?? '833456167';


        /**
         * 点击量排序
         */
        if('click_count' === $orderField) {
            $orderField      = 'year';
            $otherOrderField = 'click_count';
            $otherOrder      = $order;
        } else {
            $otherOrderField = '';
            $otherOrder      = '';
        }

        /**
         * 年份筛选
         */
        $year = Request::param('year') ?? '';

        /**
         * 高级搜索数组
         */
        $conditionArray = Request::param('condition')   ?? '';
        if( ! $conditionArray ) {
            $this->_json_error('搜索条件有误！');
        }

        foreach($conditionArray as $k => $v) {
            if( ! $v['field_value']) {
                unset($conditionArray[$k]);
            }

            if ($searchType === 1){
                //有别名的情况跳过
                continue;
            }
            /**
             * 标题搜索 匹配英文
             */
            if ($v['select_field'] == 'title'){
                //$translated_field_value =   $this->translate($v['field_value']);
                $translated_field_value = null;
		$conditionArray[$k] = [
                    "select_field"=> "title",
                    "field_value" => $v['field_value'],
                    "select_type"=> "match",
                    "select_condition"=> "or"
                ];
                if ($translated_field_value){
                    $conditionArray[] = [
                        "select_field"=> "title",
                        "field_value"=>$translated_field_value,
                        "select_type"=> "match",
                        "select_condition"=> "or"
                    ];
                }
            }

            /**
             * 主题搜索 匹配英文
             */
            if ($v['select_field'] == 'theme'){
                $conditionArray[] = [
                    "select_field"=> "title",
                    "field_value" => $v['field_value'],
                    "select_type"=> "match",
                    "select_condition"=> "or"
                ];
                $conditionArray[] = [
                    "select_field"=> "abstract",
                    "field_value" => $v['field_value'],
                    "select_type"=> "match",
                    "select_condition"=> "or"
                ];
                $conditionArray[] = [
                    "select_field"=> "keyword",
                    "field_value" => $v['field_value'],
                    "select_type"=> "match",
                    "select_condition"=> "or"
                ];
                //$translated_field_value =   $this->translate($v['field_value']);
                $translated_field_value = null;
		if ($translated_field_value){
                    $conditionArray[] = [
                        "select_field"=> "title",
                        "field_value"=>$translated_field_value,
                        "select_type"=> "match",
                        "select_condition"=> "or"
                    ];
                    $conditionArray[] = [
                        "select_field"=> "abstract",
                        "field_value"=>$translated_field_value,
                        "select_type"=> "match",
                        "select_condition"=> "or"
                    ];
                    $conditionArray[] = [
                        "select_field"=> "keyword",
                        "field_value"=>$translated_field_value,
                        "select_type"=> "match",
                        "select_condition"=> "or"
                    ];
                }
            }
        }

        /**
         * 连接es
         */
        $client = $this->getEsClient();

        /**
         * 获取查询结果
         */
        $page   = Request::param('page') ?? 1;
        $limit  = ($page - 1) * $this->pagesize;

        /**
         * 当前索引名称
         */
//        $index  = $this->currentLanguage();
        $index = 'document_zh,document_en';

        /**
         * 组装es-query
         */
        $array = $this->combineCondition($limit , $conditionArray , $searchType , $uid , $orderField , $order , $index , $searchTag , $year);
	      //dd(json_encode($array['params'],JSON_UNESCAPED_UNICODE));

	$result = $client->search(
            $array['params']
        );
        /**
         * 数据以及数据总数
         */
        $total    = $result['hits']['total'];
        if(0 == $total) {
            return $this->_json_error('未检索到结果！');
        }
        $data = $result['hits']['hits'];

        /**
         * 特殊搜索处理 （非小细胞肺癌）
         */
        $fieldValueArr = array_column($conditionArray , 'field_value');
        $fieldValue    = '非小细胞肺癌';
        if(in_array($fieldValue , $fieldValueArr)) {
            $data[0] = $this->docDetail($index);
        }

        $totalPage = ceil($total / $this->pagesize);

        /**
         * 关键词高亮
         */
        foreach($data as $key => $value) {
            if(isset($value['highlight']['author']) ) {
                $authorList = explode(";" , $value['highlight']['author'][0]);
            } else {
                $authorList = $data[$key]['_source']['author_list'] ?? '';
            }

            if(isset($value['highlight']['keyword']) ) {
                $keywordList = explode(";" , $value['highlight']['keyword'][0]);
            } else {
                $keywordList = $data[$key]['_source']['keyword_list'] ?? '';
            }

            $data[$key]['_source']['title']          = isset($value['highlight']['title'])     ? $value['highlight']['title'][0]       : $data[$key]['_source']['title'];
            $data[$key]['_source']['abstract']       = isset($value['highlight']['abstract'])  ? $value['highlight']['abstract'][0]    : $data[$key]['_source']['abstract'];
            $data[$key]['_source']['author_list']    = $authorList;
            $data[$key]['_source']['keyword_list']   = $keywordList;
        }

        if('many' === $searchType) {
            /**
             * 记录查询历史
             */
            $content          =  $array['content'] ?? '';
            $searchDesc       = '';
            $searchConditions = '';

            $countContent = count($content);
            foreach ($content as $k => $v) {
                if($k == ($countContent - 1)) {
                    $selectCondition = '';
                } else {
                    $selectCondition = $content[$k+1]['select_condition'];
                }

                $searchDesc.= '('.$v['select_field_desc'] . '=' . $v['field_value'].')' . $selectCondition . ' ';
                $searchConditions.= $v['select_condition'] . ' ';
            }

            $checkIsExistSearchHistory = History::where(
                [
                    'uid'         => $uid ,
                    'search_desc' => $searchDesc
                ]
            )->find();
            if( ! $checkIsExistSearchHistory) {
                History::create(
                    [
                        'uid'               => $uid ,
                        'content'           => json_encode($array['content'] ?? '') ,
                        'tag'               => $searchTag ,
                        'search_doc_count'  => $total ,
                        'search_desc'       => $searchDesc ,
                        'search_conditions' => $searchConditions
                    ]
                );
            }
        }

        $newArray = [];

        /**
         * 获取实际返回数据源
         */
        foreach ($data as $value) {
            $newArray[] = $value['_source'];
        }


        $combineData =  $this->dataAssemble($uid , $total, $newArray , $otherOrderField , $otherOrder);

        /**
         * 相关作者
         */
        $combineData['authors'] = $this->relatedAuthors($result['aggregations']['author_list']);

        /**
         * 搜索关键词
         */
        $combineData['keyword'] = $this->searchKeyword($conditionArray[0]['field_value'] ?? '');

        /**
         * 研究趋势
         */
        $combineData['research_trends'] = $this->researchTrends($year , $conditionArray , $index);

        /**
         * 关联研究
         */
        $combineData['associationStudy'] = $this->associationStudy($result['aggregations']['keyword_list']);

        $combineData['total_page'] = $totalPage;
        $combineData['total']      = $total;

        return $this->_json_succ(
            $combineData
        );
    }

    public function translate($text)
    {
        $url = config('translate.request_url.get_profile_url');
        $response = $this->curlGetRequest($url);
        if( ! $response) {
            return false;
        }
        $profile = json_decode($response , true) ?? '';

        if( ! $profile) {
            return $this->_json_error('系统繁忙，稍候再试！');
        }

        /**
         * 团队ID
         */
        $teamId  = $profile['data']['member'][0]['team_id'];
        $url     = config('translate.request_url.text_translate_url');
        $realRequestUrl = $url.$teamId;

        if (preg_match("/^[^\x80-\xff]+$/", $text)){
            $source = 'en';
            $target = 'zh';
        }else{
            $source = 'zh';
            $target = 'en';
        }

        /**
         * 请求参数
         */
        $requestParams = [
            "source" =>  $source,
            "target" => $target,
            "domain" => "medical" ,
            'lines'  => [
                [
                    'id'   => 0 ,
                    'text' => $text
                ]
            ]

        ];

        $response = $this->curlPostRequest($realRequestUrl , $requestParams , '9b4a6c0f23f50eb6530d6cc4a03b0e96a2f051db');
        $arr    = json_decode($response , true);
        $data   = $arr['data'];
        return $data[0]['text'] ?? '';

    }



    /**
     * 获取详情
     */
    protected function docDetail($index)
    {
        $params =  [
            'index' => $index,
            'body'  => [
                'query' => [
                    "constant_score" => [
                        "filter" => [
                            "term" => [
                                'uniq_id' => '001'
                            ]
                        ],
                    ],
                ],
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search($params);
        return $result['hits']['hits'][0] ?? [];
    }


    /**
     * 组装条件
     */
    protected function combineCondition($limit , $conditionArray , $searchType , $uid , $orderField , $order , $index , $searchTag)
    {
        if(1 === $searchTag) {
            /**
             * 普通检索 有别名和标准名称情况
             */
            $fieldVal = $conditionArray[0]['field_value'];
            $names = explode(',',$fieldVal);
//            $names = (new CdssXyDisease())->getNameAndAlias($fieldVal);
            $query = [];
            if($names) {
                $year = $this->getYear($conditionArray);
                if($year) {
                    $yearArr = explode(',', $year);
                    $query['bool']['must'][] = [
                        'range' => [
                            'year' => [
                                'gte' => $yearArr[0] ,
                                'lte' => $yearArr[1]
                            ]
                        ]
                    ];
                }
                /**
                 *作者精准查询
                 */
                if ($conditionArray[0]['select_field'] == 'author') {
                    $query['bool']['should'][] = [
                        'match_phrase' => [
                            'author_list.keyword' => $fieldVal
                        ]
                    ];
                } elseif ($conditionArray[0]['select_field'] == 'title') {
                    $query['bool']['should'][] = [
                        'match_phrase' => [
                            'title' => $fieldVal
                        ]
                    ];
                } else {
                    foreach($names as $name) {
                        $query['bool']['should'][] = [
                            'match_phrase' => [
                                'title' => $name
                            ]
                        ];
                        $query['bool']['should'][] = [
                            'match_phrase' => [
                                'abstract' => $name
                            ]
                        ];
                        $query['bool']['should'][] = [
                            'match_phrase' => [
                                'keyword' => $name
                            ]
                        ];
                    }
                }
                $query['bool']['minimum_should_match'] = 1;
                $params = [
                    'index' => $index,
                    'body'  => [
                        'size'  => $this->pagesize,
                        'from'  => $limit,
                        'query' => $query ,
                        'aggs' => [
                            'keyword_list' => [
                                'terms' => [
                                    'field'=>'keyword_list.keyword',
                                    'order' => [
                                        '_count' => 'desc'
                                    ],
                                    'size' => 20
                                ]
                            ],
                            'author_list' => [
                                'terms' => [
                                    'field'=>'author_org_list.keyword',
                                    'order' => [
                                        '_count' => 'desc'
                                    ],
                                    'size' => 20
                                ]
                            ]
                        ],
                        'highlight' => [
                            'pre_tags'  => ["<font color='red'>"],
                            'post_tags' => ['</font>'],
                            'fields'    => [
                                'title'       => new \stdClass() ,
                                'author'      => new \stdClass() ,
                                'keyword'     => new \stdClass() ,
                                'abstract'    => new \stdClass() ,
                                'album'       => new \stdClass() ,
                            ]
                        ],
                        "sort"  => $this->setOrder($orderField , $order),
                    ]
                ];
            } else {
                $params = $this->esQuery($conditionArray , $index , $limit , $orderField , $order);
            }
        }

        if(2 === $searchTag) {
            $params = $this->esQuery($conditionArray , $index , $limit , $orderField , $order);
        }

        $newConditionArray = $conditionArray;
        foreach($newConditionArray as $key => $value) {
            $newConditionArray[$key]['select_field_desc']      = $this->getFieldDesc($value['select_field']     , 'select_field');
            $newConditionArray[$key]['select_type_desc']       = $this->getFieldDesc($value['select_type']      , 'select_type');
            $newConditionArray[$key]['select_condition_desc']  = $this->getFieldDesc($value['select_condition'] , 'select_condition');
        }

        $fieldValue  = array_column($newConditionArray , 'field_value');
        $singleValue = $fieldValue[0];

        return [
            'params'  => $params ,
            'content' => $newConditionArray
        ];
    }


    protected function esQuery($conditionArray , $index , $limit , $orderField , $order)
    {
        /**
         * 高级搜索
         */
        foreach($conditionArray as $condition) {
            /**
             * 检测是否重名字段
             */
            if(stripos($condition['select_field'] , '_') != false) {
                $arr = explode('_', $condition['select_field']);
                $condition['select_field'] = $arr[0];
            }

            if('author' === $condition['select_field']) {
                if(stripos($condition['field_value'] , '-') != false) {
                    $ar = explode('-', $condition['field_value']);
                    $condition['field_value'] = $ar[0];
                }
            }

            if('and' === $condition['select_condition']) {
                if('year' === $condition['select_field']) {
                    $yearArr = explode(',' , $condition['field_value']);
                    $query['bool']['must'][] = [
                        'range' => [
                            $condition['select_field'] => [
                                'gte' => $yearArr[0] ,
                                'lte' => $yearArr[1] ,
                            ]
                        ]
                    ];
                }

                if('year' !== $condition['select_field']) {
                    if('author' === $condition['select_field']) {
                        /**
                         * author 精准查询
                         */
                        $query['bool']['must'][] = [
                            'match_phrase' => [
                                'author_list.keyword' => $condition['field_value']
                            ]
                        ];
                    }

                    /**
                     * 关键词查询
                     */
                    if('keyword' === $condition['select_field']) {
                        /**
                         * keyword 精准查询
                         */
                        $query['bool']['must'][] = [
                            'match_phrase' => [
                                'keyword_list.keyword' => $condition['field_value']
                            ]
                        ];
                    }

                    $query['bool']['must'][] = [
                        'match_phrase' => [
                            $condition['select_field'] => $condition['field_value']
                        ]
                    ];
                }
            }

            if('or' === $condition['select_condition']) {
                $query['bool']['should'][] = [
                    'match' => [
                        $condition['select_field'] => [
                            'query' => $condition['field_value'],
                            "analyzer" => "ik_max_word",
                            "operator" => "and",
                            "minimum_should_match" => "70%"
                        ]
                    ]
                ];
                $query['bool']['should'][] = [
                    'match_phrase' => [
                        $condition['select_field'] => [
                            'query' => $condition['field_value'],
                            "analyzer" => "ik_max_word",
                            "slop" => 5,
                        ]
                    ]
                ];
                $query['bool']['minimum_should_match'] = 1;
            }

            if('not' === $condition['select_condition']) {
                if('keyword' === $condition['select_field']) {
                    $condition['select_field'] = 'keyword_list.keyword';
                }
                $query['bool']['must_not'][] = [
                    'match_phrase' => [
                        $condition['select_field'] => $condition['field_value']
                    ]
                ];
            }

            if( ! $condition['select_condition']) {
                if('author' === $condition['select_field']) {
                    $query['bool']['should'][] = [
                        'match_phrase' => [
                            $condition['select_field'] => $condition['field_value']
                        ]
                    ];
                } else {
                    $query['bool']['should'][] = [
                        'match' => [
                            $condition['select_field'] => [
                                'query' => $condition['field_value'],
                                "analyzer" => "ik_max_word",
                                "operator" => "and",
                                "minimum_should_match" => "70%"
                            ]
                        ]
                    ];

                }

                $query['bool']['minimum_should_match'] = 1;
            }
        }

        //Log::info(__FUNCTION__.'query='.json_encode($query));

        $params = [
            'index' => $index,
            'body'  => [
                'size'  => $this->pagesize,
                'from'  => $limit,
                'query' => $query ,
                'aggs' => [
                    'keyword_list' => [
                        'terms' => [
                            'field'=>'keyword_list.keyword',
                            'order' => [
                                '_count' => 'desc'
                            ],
                            'size' => 20
                        ]
                    ],
                    'author_list' => [
                        'terms' => [
                            'field'=>'author_org_list.keyword',
                            'order' => [
                                '_count' => 'desc'
                            ],
                            'size' => 20
                        ]
                    ]
                ],
                'highlight' => [
                    'pre_tags'  => ["<font color='red'>"],
                    'post_tags' => ['</font>'],
                    'fields'    => [
                        'title'       => new \stdClass() ,
                        'author'      => new \stdClass() ,
                        'keyword'     => new \stdClass() ,
                        'abstract'    => new \stdClass() ,
                        'album'       => new \stdClass() ,
                    ]
                ],
                "sort"  => $this->setOrder($orderField , $order),
            ]
        ];
        return $params;
    }


    /**
     * 热点对应作者
     */
    public function refreshAuthors()
    {
        $value = Request::param('value') ?? '';
        if( ! $value) {
            return $this->_json_error('参数错误！');
        }

        $index  = $this->currentLanguage();
        $params = [
            'index' => $index,
            'body'  => [
                'size'  => 30,
                'from'  => 0,
                'query' => [
                    'match' => [
                        'title' => $value
                    ]
                ] ,
            ]
        ];

        $client = $this->getEsClient();
        $result = $client->search(
            $params
        );
        $data = $result['hits']['hits'];
        foreach ($data as $value) {
            $newArray[] = $value['_source'];
        }

        return $this->_json_succ(
            $this->authors($newArray)
        );
    }


    /**
     * 相关作者
     */
    protected function authors($data)
    {
        $authorOrg = array_column($data , 'author_org');
        $newArray  = [];
        foreach ($authorOrg as $key => $value) {
            $newArray[$key]['name']  = $value[0]['author'] ?? '';
            $newArray[$key]['org']   = $value[0]['org']    ?? '';
            $newArray[$key]['value'] = $key+351;
            $newArray[$key]['symbolSize'] = $key+40;
        }
        return $this->uniqueArr($newArray , 'name');
    }


    /**
     * 文献搜索 相关作者
     */
    protected function relatedAuthors($data)
    {
        $newArray = [];
        foreach ($data['buckets'] as $key => $value){
            $authorOrg = explode('#',$value['key']);
            $newArray[$key]['name']  = Arr::get($authorOrg,0,'');
            $newArray[$key]['org']   = Arr::get($authorOrg,1,'');
            $newArray[$key]['value'] = $value['doc_count'] + 351;
            $newArray[$key]['symbolSize'] = $value['doc_count'];
        }

        return $this->uniqueArr($newArray , 'name');
    }


    /**
     * 二维数组某个键值唯一
     */
    protected function uniqueArr($arr , $key)
    {
        $newArray = [];
        foreach ($arr as $k => $v) {
            if(empty($newArray)) {
                $newArray[] = $arr[0][$key];
            } else {
                if(in_array($v[$key] , $newArray)) {
                    unset($arr[$k]);
                } else {
                    $newArray[] = $v[$key];
                }
            }
        }
        return array_slice($arr , 0 , 10 , false);
    }


    /**
     * 获取数组中的年份
     */
    protected function getYear($conditionArray)
    {
        foreach ($conditionArray as $key => $condition) {
            if('year' === $condition['select_field']) {
                return $conditionArray[$key]['field_value'];
            }
        }
        return '';
    }


    protected function getConditionArrayYear($conditionArray)
    {
        foreach ($conditionArray as $key => $condition) {
            if($condition['select_field'] === 'year') {
                return $condition['field_value'];
            }
        }
        return '';
    }


    /**
     * 研究趋势
     */
    protected function researchTrends($year = '' , $conditionArray = '' , $index = '')
    {
        $years = $this->getConditionArrayYear($conditionArray);
        $query = [];
        if ($years){
            $year    = $years;
            $yearArr = explode(',' , $year);
            foreach ($conditionArray as $key => $condition) {
                if($condition['select_field'] === 'year') {
                    unset($conditionArray[$key]);
                }
            }

            $query['bool']['must'][] = [
                'range' => [
                    'year' => [
                        'gte' => $yearArr[0] ,
                        'lte' => $yearArr[1]
                    ]
                ]
            ];
        }

        foreach ($conditionArray as $value) {
            $query['bool']['should'][] = [
                'match_phrase' => [
                    $value['select_field'] => $value['field_value']
                ]
            ];
        }
        $query['bool']['minimum_should_match'] = 1;
        $params = [
            'index' => $index,
            'body'  => [
                'size'  => 1 ,
                'query' => $query ,
                'aggs'  => [
                    'docStat' => [
                        'terms' => [
                            'field' => 'year' ,
                            'order' => [
                                '_key' => 'asc'
                            ] ,
                            'size' => 200
                        ] ,
                        'aggs' => [
                            'citedPerYear' => [
                                'sum' => [
                                    'field' => 'citation_relate_count'
                                ]
                            ]
                        ]
                    ],
                ],
                'sort' => [
                    [
                        'year' => [
                            'order' => 'desc'
                        ]
                    ]
                ]
            ]
        ];
        $client    = $this->getEsClient();
        $result    = $client->search($params);
        return $result['aggregations']['docStat']['buckets'] ?? [];
    }



    /**
     * 关联研究
     */
    protected function associationStudy($data)
    {
        $keywordArr = array_column($data['buckets'] , 'key');

        /**
         * 热点词以及热点值
         */
        $newArray = [];
        foreach ($keywordArr as $kkk => $vvv) {
            $newArray[$kkk]['name'] = $vvv;
            $newArray[$kkk]['value'] = random_int(5000 , 10000);
        }
        return [
            'search'  => '',
            'keyword' => $newArray
        ];
    }


    /**
     * 搜索关键词
     */
    protected function searchKeyword($keyword):array
    {
        if( ! $keyword) {
            return [
                'keyword'      => '' ,
                'keyword_desc' => ''
            ];
        }

        $keywordDesc = XyZskDisease::where("name" , "like" , "%$keyword")->whereOr('alias' , 'like' , "%$keyword%")->value('sickOverview') ?? '';
        return [
            'keyword'      => $keyword ,
            'keyword_desc' => $keywordDesc
        ];
    }


    /**
     * 搜索历史
     */
    public function history()
    {
        $uid = Request::param('uid') ?? '833456167';
        if( ! $uid) {
	    $uid = 833456167;
            //return $this->_json_error('参数有误！');
        }
        $page  = Request::param('page') ?? 1;
        $limit = ($page - 1) * $this->pagesize;

        $list  =  History::where('uid' , $uid)
            ->order('id' , 'desc')
            ->limit($limit , $this->pagesize)
            ->select()
            ->toArray();

        if(empty($list)) {
            return $this->_json_succ(
                []
            );
        }
        return $this->_json_succ(
            $list
        );
    }


    /**
     * 字段描述
     */
    protected function getFieldDesc($field , $tag)
    {
        if('select_field' === $tag) {
            $fieldDesc = [
                'title'       => '标题' ,
                'author'      => '作者' ,
                'abstract'    => '摘要' ,
                'keyword'     => '关键词',
                'funds'       => '基金' ,
                'references'  => '参考文献' ,
                'doi'         => 'doi' ,
                'album'       => '期刊' ,
                'organization'=> '作者单位' ,
                'title_'      => '篇名' ,
                'author_'     => '第一作者' ,
                'author_o'    => '通讯作者' ,
                'number'      => '分类号' ,
                'references_' => '文献来源' ,
                'year'        => '发表时间'
            ];
        }

        if('select_type' === $tag) {
            $fieldDesc = [
                'term'   => '精准' ,
                'match'  => '模糊'
            ];
        }

        if('select_condition' === $tag) {
            $fieldDesc = [
                'and'   => 'And' ,
                'or'    => 'Or'
            ];
        }

        return $fieldDesc[$field] ?? '';
    }



    /**
     * 设置排序
     */
    protected function setOrder($order_field = 'id' , $order = 'asc')
    {
        return [
            $order_field => array(
                'order' => $order
            )
        ];
    }


    /**
     * 测试
     */
    public function setOrderOther($orderArray = [])
    {
        if(empty($orderArray)) {
            return [
                [
                    'id' => [
                        'order' => 'asc'
                    ]
                ]
            ];
        }

        $newOrder = [];
        foreach($orderArray as $key => $orders) {
            $newOrder[$key] = [
                $orders['order_field'] => [
                    'order' => $orders['order']
                ]
            ];
        }
        return $newOrder;
    }


    /**
     * 设置 fieldData
     */
    public function setFieldData()
    {
        $index = $this->currentLanguage();
        $type  = Request::param('type');
        $field = Request::param('field');

        if( ! $index || ! $field || ! $type) {
            return $this->_json_error('请求错误！');
        }
        $url    = "http://121.36.74.125:9200/".$index.'/'.$type.'/_mapping';

        return $this->_json_succ(
            $this->curl($url , $field)
        );
    }


    /**
     * Curl
     */
    protected function curl($url , $field)
    {
        $curl = curl_init();                            // 初始化
        curl_setopt($curl, CURLOPT_URL, $url);   // 设置抓取的url

        $data = [
            'properties' => [
                $field => [
                    'type'      => 'numeric' , // text
                    'fielddata' => true
                ]
            ]
        ];
        $jsonData = json_encode($data);

        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
                'Content-Type: application/json'
            )
        );
        curl_setopt($curl, CURLOPT_POST, 1);              // 设置post方式提交
        curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonData);      // post提交的数据
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);    // 设置获取的信息以文件流的形式返回，而不是直接输出。
        $output = curl_exec($curl);
        curl_close($curl);
        $result = json_decode($output, true);
        return $result;
    }


    /**
     * 收藏
     */
    public function docCollection()
    {
        $uid   = Request::param('uid')   ?? '833456167';
        $md5   = Request::param('md5')   ?? '';
        $tag   = Request::param('tag')   ?? '';
        $title = Request::param('title') ?? '';
        $pmid  = Request::param('PMID')   ?? '';

	if(empty($uid)){
		$uid = 833456167;
	}
	if(! $uid || ! $tag || ! $title) {
            return $this->_json_error('参数请求有误！');
        }

        $value = '';
        if ( $md5&& !$pmid){
            $value = $md5;
        }
        if ( !$md5&& $pmid){
            $md5 = $pmid;
            $value = $pmid;
        }
        $where = [
            'uid'  => $uid ,
            'md5'  => $value ,
        ];

        if('collection' === $tag) {
            $check = EsCollection::where($where)->find();
            if($check) {
                if(2 == $check->status) {
                    EsCollection::where($where)->update(
                        [
                            'status' => 1,
                            'title'  => $title
                        ]
                    );
                }
            } else {
                EsCollection::create(
                    [
                        'uid'   => $uid ,
                        'md5'   => $md5 ,
                        'title' => $title
                    ]
                );
            }
        }

        if('cancelCollection' === $tag) {
            EsCollection::where($where)->update(
                [
                    'status' => 2
                ]
            );
        }

        return $this->_json_succ();
    }



    /**
     * 我的收藏列表
     */
    public function myCollectionList()
    {
       $params = input('post.');
       $uid    = $params['uid'] ?? '833456167';

       /**
        * 搜索参数
        */
        $search = $params['search'] ?? '';
        $tag    = $params['tag']    ?? '';

        $where = [];

        /**
         * 文献标题搜索
         */
        if( $search ) {
            $where[] = ['title' , 'like' , "%$search%"];
        }

        /**
         * 文献标签搜索
         */
        if( $tag ) {
            $where[] = ['tags' , 'like' , "%$tag%"];
        }

        $page  = $params['page'] ?? 1;
        $limit = ($page - 1) * $this->pagesize;
        
	$myEsCollectionList = EsCollection::where($where)->where([
            'uid'    => $uid ,
            'status' => 1
        ])->limit($limit , $this->pagesize)->select()->toArray();
        if( ! $myEsCollectionList ) {
            return $this->_json_error('暂无收藏数据！');
        }



        /**
         * 获取收藏文献数据(es)
         */
        $client    = $this->getEsClient();
        $uniqIdArr = array_column($myEsCollectionList , 'md5');
        foreach($uniqIdArr as $uniqId) {
            $params =  [
                'index' => $this->index,
                'body' => [
                    'query' => [
                        'bool' => [
                            'should' => [
                                [
                                    "constant_score" => [
                                        "filter" => [
                                            "match" => [
                                                'uniq_id' => $uniqId
                                            ]
                                        ]
                                    ]
                                ],
                                [
                                    "constant_score" => [
                                        "filter" => [
                                            "match" => [
                                                'PMID' => $uniqId
                                            ]
                                        ]
                                    ]
                                ]
                            ]
                        ]

                    ],
                ]
            ];

            /**
             * 结果集
             */
            $result[]  = $client->search($params);
        }


        /**
         * 获取source集合
         */
        foreach ($result as $k => $v) {
            $hits[] = $result[$k]['hits']['hits'][0] ?? [];
        }
        if( ! $hits) {
            $sourceArr = [];
        } else {
            /**
             * 将mysql收藏文献标签（tags）追加到es数据
             */
            $sourceArr = array_column($hits , '_source');
            foreach ($sourceArr as $kk => $vv) {
                foreach ($myEsCollectionList as $vvv) {
                    if($vv['uniq_id'] === $vvv['md5']) {
                        $sourceArr[$kk]['tags'] = $vvv['tags'];
                    }
                }
                $sourceArr[$kk]['is_collection'] = $this->checkIsCollectionDoc($uid , $vv['uniq_id']);
                $sourceArr[$kk]['click_count']   = ClickCount::where('md5' , $vv['uniq_id'])->value('click_count') ?? 0;
            }
        }

        /**
         * 收藏文献标签集合
         */
        $newTagList = [];
        foreach ($myEsCollectionList as $tkey => $tval) {
            $newTagList[] = explode(',' , $tval['tags']);
        }
        $newTagList = array_filter($this->mergeArray($newTagList));


        return $this->_json_succ(
            [
                'tags_list' => $newTagList ,
                'list'      => $sourceArr
            ]
        );
    }


    /**
     * 合并二维数组下的多个一维数组
     */
    protected function mergeArray($arr)
    {
        return call_user_func_array('array_merge' , $arr);
    }


    /**
     * 添加收藏标签
     * @return
     */
    public function docCollectionTags()
    {
        $uid  = Request::param('uid')   ?? '833456167';
        $md5  = Request::param('md5')   ?? '';
        $tags = Request::param('tags')  ?? [];

        if( ! $uid || ! $md5 || empty($tags)) {
            return $this->_json_error('参数请求有误！');
        }

        $collection = EsCollection::where([
            'uid'  => $uid ,
            'md5'  => $md5 ,
            'status'  => 1 ,
        ])->find();

        if ( ! $collection ) {
            return $this->_json_error('文献不存在');
        }
        $collection->tags = implode(',' , $tags);
        $collection->save();

        return $this->_json_succ();
    }



    /**
     * 列表返回统一封装
     */
    protected function dataAssemble($uid , $total , $data , $otherOrderField = ''  , $otherOrder = ''):array
    {
        if(empty($data)) {
            return [];
        }


//        foreach($data as $key => $value) {
//            if(stripos($value['abstract'] , '<正>') !== false) {
//                $data[$key]['abstract'] = str_replace('<正>' , ' ' , $value['abstract']);
//            }
//            /**
//             * 文献点击量 是否收藏
//             */
//            $data[$key]['is_collection'] = $this->checkIsCollectionDoc($uid , $value['uniq_id']);
//            $data[$key]['click_count']   = ClickCount::where('md5' , $value['uniq_id'])->value('click_count') ?? 0;
//        }
        $md5Arr = [];
        /**
         * 处理文献中带 <正>
         */
        foreach($data as $key => $value)
        {
            if(isset($value['abstract'])) {
                $data[$key]['abstract'] = str_replace('<正>' , ' ' , $value['abstract']);
            }

            if(isset($value['periodical_md5'])) {
                $md5Arr[] = $value['periodical_md5'];
            }
        }

        //文献 收藏 点击量
        $md5Res = EsCollection::where(['uid' => $uid])->whereIn('md5', $md5Arr)->select()->toArray();
        $clickCountRes = ClickCount::whereIn('md5', $md5Arr)->select()->toArray();
        foreach ($data as $key => $value) {
            $data[$key]['is_collection'] = 2;
            $data[$key]['click_count'] = 0;
            if (isset($value['periodical_md5'])) {
                if ($collectionKey = array_search($value['periodical_md5'], array_column($md5Res, 'md5'))) {
                    if ($md5Res[$collectionKey]['status'] != 2) {
                        $data[$key]['is_collection'] = 1;
                    }
                }

                if ($clickCountKey = array_search($value['periodical_md5'], array_column($clickCountRes, 'md5'))) {
                    $data[$key]['click_count'] = $clickCountRes[$clickCountKey]['click_count'];
                }
            }
        }


        /**
         * 点击量动态数组排序
         */
        if('click_count' === $otherOrderField) {
            $click_count = array_column($data , 'click_count');
            $otherOrder  = 'asc' === $otherOrder ? SORT_ASC : SORT_DESC;
            array_multisort($click_count , $otherOrder , $data);
        }

        return [
            'total'      => $total,
            'total_page' => ceil($total / $this->pagesize),
            'data'       => $data
        ];
    }


    /**
     * 用户是否收藏文献
     * 1.已收藏 2.未收藏
     */
    protected function checkIsCollectionDoc($uid , $uniq_id)
    {
        $check = EsCollection::where(['uid' => $uid , 'md5' => $uniq_id])->find();
        if( ! $check || 2 == $check->status) {
            return 2;
        }
        return 1;
    }



    /**
     * 换一批
     */
    public function randomDoc()
    {
        $tag   = Request::param('tag') ?? $this->index;
        $uid   = Request::param('uid') ?? '833456167';

        $index = $tag;
        $field = Request::param('field') ?? 'title , periodical_md5';

        $page  = Request::param('page') ?? 1;
        $limit = ($page - 1) * 10;

        //$index  = $this->currentLanguage();
        $index = 'document_zh';
	$params =  [
            'index' => $index,
            'body'  => [
                'from'  => $limit,
                'size'  => 10,
                'query' => [
                    'match_all'  => (object)[] ,            // 查询全部
                ],
                "_source" => ['title' , 'periodical_md5' , 'uniq_id'],  // 获取制定字段
                //"sort"    => $this->setOrder('year' , 'desc'),
            ],
        ];
        $result = $this->esCommonGetData($params);
        return $this->_json_succ($result);
    }


    /**
     * 相关推荐
     *
     * @param  $tag   string  模块标识  (学科分析 ｜ 学者分析 ｜ 期刊分析)
     * @param  $value string  分析值
     * @param  $type  string  类型     (最新 ｜ 最高)
     * @return Json
     */
    public function relationRecommend()
    {
        $org = Request::param('org')   ?? '';
        $tag   = Request::param('tag')   ?? '';
        $value = Request::param('value') ?? '';
        $type  = Request::param('type')  ?? 'highest';

        if( ! $tag || ! $value || ! $type) {
            return $this->_json_error('请求参数有误！');
        }

        $page  = Request::param('page') ?? 1;
        $limit = ($page - 1) * $this->pagesize;

        if('department' === $tag) {
            $selectField = 'title';
            $selectType  = 'match_phrase';
        }


        if('album' === $tag) {
            $selectField = 'album.keyword';
            $selectType  = 'match';
        }

        if('highest' === $type) {
            $orderField = 'citation_relate_count';
            $order      = 'desc';
        }

        if('newest' === $type) {
            $orderField = 'year';
            $order      = 'desc';
        }

        if('author' === $tag) {
            $query =  [
                'bool' => [
                    'must' => [
                        [
                            'nested' => [
                                'path' => 'author_org',
                                'query' => [
                                    'bool' => [
                                        'must' => [
                                            [
                                                'match_phrase' => [
                                                    'author_org.author' => $value
                                                ]
                                            ],
                                            [
                                            'match_phrase' => [
                                                'author_org.org' => $org
                                            ]
                                        ]
                                        ]
                                    ]
                                ]
                            ]
                        ],
                        [
                            'match_phrase' => [
                                'author' => $value
                            ]
                        ],
                        [
                            'range' => [
                                'year' => [
                                    'gte' => 2002 ,
                                    'lte' => 2040
                                ]
                            ]
                        ]
                    ]
                ]
            ];
        }else{
            $query =  [
                'bool' => [
                    'must' => [
                        [
                            $selectType => [
                                $selectField => $value
                            ]
                        ],
                        [
                            'range' => [
                                'year' => [
                                    'gte' => 2002 ,
                                    'lte' => 2040
                                ]
                            ]
                        ]
                    ]
                ]
            ];
        }

        $index  = $this->currentLanguage();
        //$source = ["author" , "title" , "year" , "citation_relate_count" , "album" , "periodical_md5" , "author_list"];
        $params = [
            'index'   => $index ,
            'from' => $limit ,
            'size' => $this->pagesize,
            'body'    => [
                'query' =>  $query,
                'highlight' => [
                    'pre_tags'  => ["<font color='red'>"],
                    'post_tags' => ['</font>'],
                    'fields'    => [
                        'author' => new \stdClass() ,
                    ]
                ],
                'sort' => $this->setOrder($orderField , $order)
            ]
        ];

        $client = $this->getEsClient();
        $esData = $client->search(
            $params
        );

        $result = $esData['hits']['hits'];
        $data   = $result;

        /**
         * 关键词高亮
         */
        foreach($data as $key => $value) {
            if(isset($value['highlight']['author']) ) {
                $authorList = explode(";" , $value['highlight']['author'][0]);
            } else {
                $authorList = $data[$key]['_source']['author_list'];
            }
            $data[$key]['_source']['author_list'] = $authorList;
        }

        return $this->_json_succ(
            [
                'total'      => $esData['hits']['total'],
                'total_page' => ceil($esData['hits']['total'] / $this->pagesize) ,
                'list'       => array_column($data , '_source')
            ]
        );
    }


    /**
     * 清除
     */
    public function clear()
    {
        $uid = Request::param('uid') ?? '833456167';
        $id  = Request::param('id')  ?? '';
        $tag = Request::param('tag') ?? '';

        if(! $uid || ! $tag) {
            return $this->_json_error('请求有误！');
        }
        if('clear' === $tag) {
            History::where('uid' , $uid)->delete();
        } else {
            if($id) {
                History::where('id' , $id)->delete();
            }
        }
        return $this->_json_succ();
    }

}
