<?php

/**
 * 用户账户服务
 *
 * @author lixiaolin
 * @Date: 2021/8/31
 * @Time: 下午9:56
 * @Email: lixiaolin@bluearp.com
 * @version 1.0
 * @copyright BlueCity
 */

namespace App\Services;

use App\Inc\CacheInc;
use App\Inc\CommonInc;
use BlueCity\Core\Inc\ErrorInc;
use BlueCity\Core\Service\Service;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class CommonService extends Service
{
    /**
     * 获取
     * @param db $db 数据库
     * @param array $params where条件
     * @param array $select 查询字段
     * @param array $orderby 排序规则
     * @param array $type 查询方式
     * @param array $limit 查询数量
     * @return array|mixed
     */
    public static function getMysqlData( $db , $params , $select = [] , $orderby = [] , $type = 'get' , $limit ='')
    {
        //$db = new Admin();
        if($params){
            $where = CommonService::jointWhere($params);
            $db = $db->whereRaw($where);
        }
        if($orderby){
            foreach( $orderby as $k => $v ){
                $db = $db->orderBy($k,$v);
            }
        }
        if($limit){
            $db = $db->limit($limit);
        }
        if($type == 'value'){
            $list = $db->value($select[0]);
        }elseif ( $type == 'count' ){
            $list = $db->count();
        }elseif ( $type == 'pluck' ){
            $list = $db->pluck($select[0]);
            if( $list ){
                $list = CommonService::dataToArray($list);
            }
        }else{
            if($select){
                $db = $db->select($select);
            }
            if($type == 'first'){
                $list = $db->first();
            }else{
                $list = $db->get();
            }
            if( $list ){
                $list = CommonService::dataToArray($list);
            }
        }
        return $list;
    }
    /**|---------------------------------------------------------------------------------
     * 外层数组内层对象转数组
     * @param array $list   带转化数据
     * @return array
     * @author dou <2021/07/16>
     * |---------------------------------------------------------------------------------
     */
    public static function dataToArray ( $list ){
        return json_decode(json_encode($list),true);
    }
    /**|---------------------------------------------------------------------------------
     * @name  拼接查询语句
     * @param array $params 待拼接参数
     * @return \Illuminate\Http\JsonResponse
     * @author dou <2021/07/26>
     * |---------------------------------------------------------------------------------
     */
    public static function jointWhere ( $params ){
        $condition = [];
        foreach( $params as $k => $v ){
            if(strpos($k,'_noteq')){//不等于
                $key_length = strlen($k);
                $range_length = strlen('_noteq');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." != '".$v."'";
            }elseif ( strpos($k,'_llike') ){//左包含
                $key_length = strlen($k);
                $range_length = strlen('_llike');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." like '%".$v."'";
            }elseif ( strpos($k,'_rlike') ){//右包含
                $key_length = strlen($k);
                $range_length = strlen('_rlike');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." like '".$v."%'";
            }elseif ( strpos($k,'_like') ){//包含
                $key_length = strlen($k);
                $range_length = strlen('_like');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." like '%".$v."%'";
            }elseif ( strpos($k,'_between') ){//区间取值
                $key_length = strlen($k);
                $range_length = strlen('_between');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." between '".$v[0]."' and '".$v[1]."'";
            }elseif ( strpos($k,'_searchin') ){//在数据内in
                $key_length = strlen($k);
                $range_length = strlen('_searchin');
                $k = substr($k,0,$key_length-$range_length);
                if(is_array($v)){
                    $condition[] = $k." in ('".implode("','",$v)."')";
                }else{
                    $condition[] = $k." in (".$v.")";
                }
            }elseif ( strpos($k,'_notin') ){//不在在数据内in
                $key_length = strlen($k);
                $range_length = strlen('_notin');
                $k = substr($k,0,$key_length-$range_length);
                if(is_array($v)){
                    $condition[] = $k." not in ('".implode("','",$v)."')";
                }else{
                    $condition[] = $k." not in (".$v.")";
                }
            }elseif ( strpos($k,'_searchgt') ){//大于
                $key_length = strlen($k);
                $range_length = strlen('_searchgt');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." > '".$v."'";
            }elseif ( strpos($k,'_searcheqgt') ){//大于等于
                $key_length = strlen($k);
                $range_length = strlen('_searcheqgt');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." >= '".$v."'";
            }elseif ( strpos($k,'_searchlt') ){//小于
                $key_length = strlen($k);
                $range_length = strlen('_searchlt');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." < '".$v."'";
            }elseif ( strpos($k,'_searcheqlt') ){//小于等于
                $key_length = strlen($k);
                $range_length = strlen('_searcheqlt');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." <= '".$v."'";
            }elseif ( strpos($k,'_findinset') ){
                $key_length = strlen($k);
                $range_length = strlen('_findinset');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = "FIND_IN_SET(".$v.",".$k.")";
            }elseif ( strpos($k,'_isnull') ){//是空的
                $key_length = strlen($k);
                $range_length = strlen('_isnull');
                $k = substr($k,0,$key_length-$range_length);
                $condition[] = $k." is null";
            }elseif ( strpos($k,'next_level') ){//下一级拆分
//				$key_length = strlen($k);
//				$range_length = strlen('_searchor');
//				$k = substr($k,0,$key_length-$range_length);
                $condition[] = CommonService::joinnext($v);
            }elseif ( strpos($k,'_searchor') ){//或关系查询
//				$key_length = strlen($k);
//				$range_length = strlen('_searchor');
//				$k = substr($k,0,$key_length-$range_length);
                $condition[] = CommonService::jointOr($v);
            }else{
                $condition[] = $k." = '".$v."'";
            }
        }
        return implode(' and ',$condition);
    }

    /**|---------------------------------------------------------------------------------
     * @name  拼接查询or语句
     * @param array $params 待拼接参数
     * @return \Illuminate\Http\JsonResponse
     * @author dou <2021/80/02>
     * |---------------------------------------------------------------------------------
     */
    public static function jointOr ( $params ){
        $condition = [];
        foreach( $params as $k => $v ){
            if ( strpos($k,'next_level') ){
                $data = [];
                foreach($v as $ka => $va){
                    $data[$ka] = $va;
                }
                $condition[]= "(".CommonService::jointWhere($data).")";
            }else {
                $data = [];
                $data[$k] = $v;
                $condition[]= CommonService::jointWhere($data);
            }
        }
        return "(".implode(' or ',$condition).")";
    }

    /**|---------------------------------------------------------------------------------
     * @name 拼接多重查询
     * @param array $params 待拼接参数
     * @return \Illuminate\Http\JsonResponse
     * @author dou 2022/1/8 10:48
     * |---------------------------------------------------------------------------------
     */
    public static function joinnext ( $params ){
        $condition = [];
        foreach( $params as $k => $v ){
            $data = [];
            $data[$k] = $v;
            $condition[]= CommonService::jointWhere($data);
        }
        return implode(' and ',$condition);
    }

    /**
     * 获取对应位置按钮
     * @param array $my_button  需展示按钮
     * @param array $all_button  可操作按钮
     * @param string $type  按钮位置 type=1横排  type=2记录后
     * @return array|mixed
     */
    public static function getButton ( $my_button , $all_button , $type )
    {
        if ($my_button && $all_button){
            $my_button = explode(',',$my_button);
            $num=0;
            foreach ($all_button as $key=>$value){
                if(in_array($value['pri_operate_method'],$my_button) && ($value['pri_position'] == $type)){
                    $button[]=$value;
                }
                $num++;
            }
            if (isset($button)){
                return $button;
            }else{
                return [];
            }
        }else{
            return [];
        }
    }

    /**
     * 获取对应位置按钮
     * @param array $my_button  需展示按钮
     * @param array $all_button  可操作按钮
     * @param string $type  按钮位置 type=1横排  type=2记录后
     * @return array|mixed
     */
    public static function getAppletButton ( $my_button , $all_button , $type )
    {
        if ($my_button && $all_button){
            $my_button = explode(',',$my_button);
            $num=0;
            foreach ($all_button as $key=>$value){
                if(in_array($value['pri_operate_method'],$my_button) && $value['have_pri'] == 1){
                    $button[]=$value;
                }
                $num++;
            }
            if (isset($button)){
                return $button;
            }else{
                return [];
            }
        }else{
            return [];
        }
    }

    /**
     * 获取列表按钮
     * @param array $listdata  列表页需展示按钮
     * @param array $all_button  可操作按钮
     * @return array|mixed
     */
    public static function getListButton ( $listdata , $all_button)
    {
        $button = self::getButton(implode(',',$listdata),$all_button,2);
        if ($button){
            foreach ($button as $ki => $vi) {
                $sort[] = $vi['pri_sord'];
            }
            array_multisort($sort, SORT_NUMERIC, SORT_DESC, $button);
            $data['button_one'][] = $button[0];
            if (count($button)==1){
                $data['button_two'] = [];
                $data['button_three'] = [];
            }elseif ((count($button)>1)){
                $data['button_two']=array_slice($button,1);
                $data['button_three'] = [];
            }
            unset($button);

        }else{
            $data['button_one'] = [];
            $data['button_two'] = [];
            $data['button_three'] = [];
        }
        return $data;
    }

    /**
     * 获取顶部按钮
     * @param string $topdata  顶部非搜索栏内容
     * @param string $searchdata  顶部搜索栏内容
     * @param array $all_button  可操作按钮
     * @return array|mixed
     */
    public static function getTopButton ( $topdata , $searchdata , $all_button)
    {
        $data=[];
        $data['button_top'] = self::getButton($topdata,$all_button,1);
        $data['button_search'] = self::getButton($searchdata,$all_button,4);
        return $data;
    }

    /**
     * 获取列表按钮 
     * @param array $listdata  列表页需展示按钮
     * @param array $all_button  可操作按钮
     * @return array|mixed
     */
    public static function getAppletListButton ( $listdata , $all_button)
    {
        $button = self::getAppletButton(implode(',',$listdata),$all_button,2);
        if ($button){
            foreach ($button as $ki => $vi) {
                $sort[] = $vi['pri_sord'];
            }
            array_multisort($sort, SORT_NUMERIC, SORT_DESC, $button);
            if (count($button)<=3){
                $data['button_one'] = $button;
                $data['button_two'] = [];
            }elseif ((count($button)>3)){
                array_multisort($sort, SORT_NUMERIC, SORT_ASC, $button);
                $data['button_one']=array_slice($button,0,3);
                foreach ($data['button_one'] as $ki => $vi) {
                    $sort1[] = $vi['pri_sord'];
                }
                array_multisort($sort1, SORT_NUMERIC, SORT_DESC, $data['button_one']);
                $data['button_two'] = array_slice($button,3);
            }
            unset($button);

        }else{
            $data['button_one'] = [];
            $data['button_two'] = [];
            $data['button_three'] = [];
        }
        return $data;
    }

    /**
     * @name 日志
     * @param $msg
     * @param $data
     * @param $number
     * @param string $filename
     * @author du
     * @date 2023/6/16
     * @Time: 16:36
     */
    public static function addLog ( $msg ,  $data , $number , $filename = '' ){
        if(!$filename){
            $filename = 'DataLog'.date('Ym');
        }else{
            $time = date('Ym');
            if(strpos($filename,$time) !== false){
            }else{
                $filename = $filename.$time;
            }
        }
        $file_path = "./filedata/".$filename.".txt";
        if(!is_dir('./filedata')){
            mkdir(iconv("UTF-8", "GBK", './filedata'),0777,true);
        }
        $myfile = fopen($file_path, "a");
        $txt = $msg.":".$data."--".$number.'--'.date("Y-m-d H:i:s")."\r\n";
        fwrite($myfile, $txt);
        fclose($myfile);
    }
    
    /**|---------------------------------------------------------------------------------
     * @name 筛选信息
     * @param string $data 待筛选信息
     * @param string $screen_data 筛选信息
     * @param string $type 筛选类型 1删除 2判定
     * @retrun /multitype:string
     * @author dou 2023-06-26 026 上午 10:06:53
     * |---------------------------------------------------------------------------------
    */
    public static function screenData ( $data , $screen_data , $type ){
        if($type == 1){
            if(!strstr($data,$screen_data)){
                return $data;
            }else{
                return str_replace($screen_data,'',$data);
            }
        }else{
            if(strstr($data,$screen_data)){
                return true;
            }else{
                return false;
            }
        }
    }
    /**|---------------------------------------------------------------------------------
     * @name 模拟post请求
     * @param string $url 请求链接
     * @param array $param 请求参数
     * @param array $header 请求头
     * @retrun multitype:array
     * @author dou 2023/07/06 17:51
     * |---------------------------------------------------------------------------------
     */
    public static function requestPost($url,$param,$header='') {
        /*$header = array(
            'Content-Type: application/json',
        );*/
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        if($header!=''){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        // https 请求//如果地址是https协议，且CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST打开了，则需要加载证书
        if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        if (is_array($param) && 0 < count($param)) {
            $postMultipart = false;
            foreach ($param as $k => $v) {
                if ('@' == substr($v, 0, 1)) {
                    $postMultipart = true;
                    break;
                }
            }
            unset($k, $v);
            if ($postMultipart) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, $param);// post传输数据
            } else {
                curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($param));
            }
        }else{
            curl_setopt($ch, CURLOPT_POSTFIELDS, $param);// post传输数据
        }
        $response = curl_exec($ch);
        curl_close($ch);
        return trim($response);
    }

    /**|---------------------------------------------------------------------------------
     * @name 坐标获取省市区
     * @param string location 经纬度
     * @param string get_poi 是否返回周边地点（POI）列表，可选值：0 不返回(默认)1 返回
     * @param string poi_options 周边POI（AOI）列表控制参数： 参考https://lbs.qq.com/service/webService/webServiceGuide/webServiceGcoder
     * @retrun /multitype:array
     * @author dou 2023/7/18 14:39
     * |---------------------------------------------------------------------------------
    */
    public static function getDress ( $location , $get_poi = 0 ){
        $url = "https://apis.map.qq.com/ws/geocoder/v1/?location=".$location."&key=FGQBZ-PGI64-KX5U5-XNP3V-TIWRH-X6FYT&get_poi=".$get_poi;
        $data = file_get_contents($url);
        $data = json_decode($data,true);
        $return['code'] = 0;
        if($data['status'] == 0){
            $return['code'] = 1;
            $return['data'] = $data['result'];
        }
        return $return;
    }

    /**|---------------------------------------------------------------------------------
     * @name 获取物理地址对应经纬度
     * @param string $city 所属城市
     * @param string $address 详细地址
     * @retrun multitype:array
     * @author dou 2021/8/16 0:33
     * |---------------------------------------------------------------------------------
     */
    public static function jingwei($city, $address)
    {
        try {
            $url = "http://restapi.amap.com/v3/geocode/geo?key=bf7919b601432722e4353ba6358e9c10&address='" . $address . "'&city='" . $city . "'&output='json'";

            $data = file_get_contents($url);
            $data = json_decode($data,true);
            if ($data['status'] == '1' && $data['geocodes']) {
                return $data['geocodes'][0]['location'];
            } else {
                return '';
            }
        } catch (\Exception $e) {
            return $e->getMessage();
        }

    }

    /**|---------------------------------------------------------------------------------
     * @name  提取二维数字键值做主键所有参数保留
     * @param array $data 数组数据
     * @param string $key 提取键值
     * @param string $type 提取键值在数据中是否唯一  1唯一 2不唯一
     * @return \Illuminate\Http\JsonResponse
     * @author dou <2021/07/27>
     * |---------------------------------------------------------------------------------
     */
    public static function jointArrayKey ( $data , $key , $type = '1'){
        if($type == '1'){
            $key = array_column($data,$key);
            $data = array_combine($key,$data);
        }else{
            $list = [];
            foreach( $data as $k => $v ){
                $list[$v[$key]][] = $v;
            }
            $data = $list;
        }
        return $data;
    }

    /**|---------------------------------------------------------------------------------
     * @name 系统验证函数结果转化为字符串
     * @param array $Validator 验证结果
     * @return \Illuminate\Http\JsonResponse
     * @author Dou <2023/09/15>
     * |---------------------------------------------------------------------------------
     */
    public static function validatorToString($Validator)
    {
        $data = [];
        foreach ($Validator as $k => $v) {
            $data[] = $v[0];
        }
        return implode(',', $data);
    }

    /**|---------------------------------------------------------------------------------
     * @name 判定两个日期相差天数
     * @param string $date1 开始时间
     * @param string $date2 结束时间
     * @retrun /multitype:array
     * @author dou 2023/9/18 16:49
     * |---------------------------------------------------------------------------------
    */
    public static function getDiffDate( $date1 , $date2 )
    {
        $date1 = strtotime($date1);
        $date2 = strtotime($date2);
        if($date1>$date2){
            return 0;
        }elseif ($date1 == $date2){
            return 1;
        }else{
            return round(($date2-$date1)/3600/24)+1;
        }
    }

    /**|---------------------------------------------------------------------------------
     * @name 开启msql事务
     * @author dou 2021/11/19 17:05
     * |---------------------------------------------------------------------------------
     */
    public static function startmysql()
    {
        DB::connection()->enableQueryLog();#开启执行日志
    }

    /**|---------------------------------------------------------------------------------
     * @name 输出msql事务
     * @author dou 2021/11/19 17:05
     * |---------------------------------------------------------------------------------
     */
    public static function showmysql()
    {
        $query = DB::getQueryLog()[0];//sql数组
        $bindings = $query['bindings'];//sql参数
        $sql = $query['query'];//sql语句
        //正则替换
        foreach ($bindings as $replace) {
            $value = is_numeric($replace) ? $replace : "'" . $replace . "'";
            $sql = preg_replace('/\?/', $value, $sql, 1);
        }
        return $sql;
    }

    /**|---------------------------------------------------------------------------------
     * @name 重置数组键从0开始
     * @param srray $list 需重置数据
     * @retrun /multitype:array
     * @author dou 2021/9/10 10:54
     * |---------------------------------------------------------------------------------
     */
    public static function resetListKey($list)
    {
        $data = [];
        foreach ($list as $k => $v) {
            $data[] = $v;
        }
        return $data;
    }

    /**
     * 获取符合字段和字段值的数组集合
     * @param array $data 待过滤数组
     * @param array $conditions 检索条件
     * @return array 返回所有符合要求的数组集合
     */
    public static function arrayFilterFieldValue($data, $conditions)
    {
        $field = array_keys($conditions[0])[0];
        $value = array_values($conditions[0])[0];
        $data = array_filter($data, function ($row) use ($field, $value) {
            if (isset($row[$field])) {
                if (is_array($value)) {
                    return in_array($row[$field], $value);
                } else {
                    return $row[$field] == $value;
                }
            }
        });
        unset($conditions[0]);
        $conditions = array_values($conditions);
        if ($conditions) {
            return CommonService::arrayFilterFieldValue($data, $conditions);
        } else {
            return $data;
        }
    }

    /**|---------------------------------------------------------------------------------
     * @name 验证函数
     * @param $check 需要校验参数
     * @param $parameter 传输参数
     * @param $rules 验证参数对应中文注释
     * @return \Illuminate\Http\JsonResponse
     * @author Dou <2021/04/25>
     * |---------------------------------------------------------------------------------
     */
    public static function checkKey($check, $parameter, $rules = [])
    {
        $flag['code'] = 1;
        $flag['data'] = [];
        $paramet = [];
        foreach ($parameter as $k => $v) {
            if ($v !== '') {
                $paramet[] = $k;
            }
        }
        foreach ($check as $k => $v) {
            if (!in_array($v, $paramet)) {
                $flag['code'] = 2;
                $flag['data'][] = $rules[$v] ?? $v;
            } else {
                if ($parameter[$v] === '' || $parameter[$v] === null) {
                    $flag['code'] = 2;
                    $flag['data'][] = $rules[$v] ?? $v;
                }
            }
        }
        if ($flag['code'] == 2) {
            $flag['data'] = implode(",", $flag['data']);
        }else{
            $flag['data'] = '';
        }
        return ['code' => $flag['code'], 'msg' => '参数'.$flag['data'].'未填写,或值为空', 'data' => []];
    }
}
