<?php
/**
 * Created by PhpStorm.
 * User: zilongs
 * Date: 20-9-23
 * Time: 上午10:56
 */

use Illuminate\Support\Facades\Log;
use App\Exceptions\ExitOutException;
use App\Models\SystemConfig;
use App\Models\TimePeriod;

//统一输出格式话的json数据
if (!function_exists('out')) {
    function out($data = null, $status = 0, $message = 'success', $exceptionData = false)
    {
        $out = ['status' => $status, 'message' => $message, 'data' => $data];

        if ($exceptionData !== false) {
            trace([$message => $exceptionData], 'error');
        }

        return response()->json($out);
    }
}

//统一异常输出格式话的json数据
if (!function_exists('exit_out')) {
    function exit_out($data = null, $status = 0, $message = 'success', $exceptionData = false)
    {
        $out = ['status' => $status, 'message' => $message, 'data' => $data];

        if ($exceptionData !== false) {
            trace([$message => $exceptionData], 'error');
        }

        $json = json_encode($out, JSON_UNESCAPED_UNICODE);

        throw new ExitOutException($json);
    }
}

//日志记录
if (!function_exists('trace')) {
    function trace($log = '', $level = 'info')
    {
        Log::log($level, $log);
    }
}


if (!function_exists('upDecimal')) {

    /**
     * 对价格进行向上取整
     * @param $price    价格
     * @param $decimal  保留小数位数
     */
    function upDecimal($price, $decimal = 2){
        $data1 = pow(10, $decimal);
        $data2 = ceil(bcmul($price, $data1,10));
        $data3 = bcdiv($data2, $data1, $decimal);
        return $data3;
    }
}

//AES加密
if (!function_exists('aes_encrypt')) {
    function aes_encrypt($data)
    {
        if (is_array($data)) {
            $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        }
        $key = config('config.aes_key');
        $iv  = config('config.aes_iv');

        $cipher_text = openssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);
        $cipher_text = base64_encode($cipher_text);

        return urlencode($cipher_text);
    }
}

//AES解密
if (!function_exists('aes_decrypt')) {
    function aes_decrypt($encryptData)
    {
        $encryptData = urldecode($encryptData);
        $encryptData = base64_decode($encryptData);

        $key = config('config.aes_key');
        $iv  = config('config.aes_iv');

        $original_plaintext = openssl_decrypt($encryptData, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv);

        return json_decode($original_plaintext, true);
    }
}

//获取distance的sql字段
if (!function_exists('get_distance_field')) {
    function get_distance_field($latitude, $longitude)
    {
        if (empty($latitude) || empty($longitude)) {

            return '未知 distance';
        }

        return 'if(longitude=0 and latitude=0,未知,round(6378.138*2*asin(sqrt(pow(sin( (' . $latitude . '*pi()/180-latitude*pi()/180)/2),2)+cos(' . $latitude . '*pi()/180)*cos(latitude*pi()/180)* pow(sin((' . $longitude . '*pi()/180-longitude*pi()/180)/2),2)))*1000)) distance';
    }
}

//获取用户的distance的sql字段
if (!function_exists('get_user_distance_field')) {
    function get_user_distance_field($user)
    {
        $coordinate = get_user_coordinate($user);
        $latitude = $coordinate['latitude'];
        $longitude = $coordinate['longitude'];
        if (empty($latitude) || empty($longitude)) {
            return '"未知" distance';
        }

        return 'if(longitude=0 and latitude=0,"未知",round(6378.138*2*asin(sqrt(pow(sin( (' . $latitude . '*pi()/180-latitude*pi()/180)/2),2)+cos(' . $latitude . '*pi()/180)*cos(latitude*pi()/180)* pow(sin((' . $longitude . '*pi()/180-longitude*pi()/180)/2),2)))*1000)) distance';

    }
}

//构建单号
if (!function_exists('build_sn')) {
    function build_sn($id, $len = 2, $prefix = '')
    {
        $idx = 0 - $len;
        $suffix = substr($id, $idx);
        $suffix = str_pad($suffix, $len, '0', STR_PAD_LEFT);

        $sn = $prefix.substr(date('YmdHis'), 2).$suffix;

        return $sn;
    }
}

//生日转年龄
if (!function_exists('birthday_to_age')){
    function birthday_to_age($birthday)
    {
        if($birthday==null)
        {
            return "0岁";
        }
        list($year, $month, $day) = explode("-", $birthday);
        $year_diff = (date("Y") - $year) > 0 ? date("Y") - $year.'岁':'';
        $month_diff = (date("m") - $month) > 0 ? date("m") - $month.'个月':'';
        $day_diff = (date("d") - $day) > 0 ? date("d") - $day.'天':'';
        if ($day_diff < 0 || $month_diff < 0) {
            $year_diff--;
        }
        return $year_diff.$month_diff.$day_diff ;
    }
}
//计算经纬度两点之间距离(返回为米)
if (!function_exists('get_distance')) {
    function get_distance($lat1, $lng1, $lat2, $lng2)
    {
        if (empty($lat1) || empty($lng1) || empty($lat2) || empty($lng2)) {
            return '未知';
        }
        $earthRadius = 6378138;
        $lat1 = ($lat1 * pi()) / 180;
        $lng1 = ($lng1 * pi()) / 180;
        $lat2 = ($lat2 * pi()) / 180;
        $lng2 = ($lng2 * pi()) / 180;
        $calcLongitude = $lng2 - $lng1;
        $calcLatitude = $lat2 - $lat1;
        $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
        $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
        $calculatedDistance = $earthRadius * $stepTwo;

        return number_format($calculatedDistance, 2, '.', '');
    }
}

//获取用户坐标
if (!function_exists('get_user_coordinate')) {
    function get_user_coordinate($user)
    {
        $req = request()->post();
        if (empty($req['latitude']) || empty($req['longitude'])) {
            $latitude = $user['latitude'] ?? 0;
            $longitude = $user['longitude'] ?? 0;
        }
        else {
            $latitude = $req['latitude'];
            $longitude = $req['longitude'];
        }

        return ['latitude' => $latitude, 'longitude' => $longitude];
    }
}

//获取用户距离
if (!function_exists('get_user_distance')) {
    function get_user_distance($user, $lat, $lng)
    {
        $coordinate = get_user_coordinate($user);
        $data = get_distance($coordinate['latitude'], $coordinate['longitude'], $lat, $lng);
        return $data;
    }
}


if (!function_exists('numBirthday')){
    /**
     * 生日转年龄
     * @author Yuanhang Liu & Xiaoyun Liu
     * @param $birthday 2020-10-14 00:48
     * @return string
     */
    function numBirthday($birthday){

        if ($birthday){
            try {
                list($year,$month,$day) = explode("-",$birthday);
                $year_diff = (date("Y") - $year)>0?date("Y") - $year.'岁':'';
                $month_diff = (date("m") - $month)>0?date("m") - $month.'个月':'';
                $day_diff  = (date("d") - $day)>0?date("d") - $day.'天':'';
                if ($day_diff < 0 || $month_diff < 0)
                    $year_diff--;
                return $year_diff.$month_diff.$day_diff ;
            }catch (Exception $e){

                return '';
            }

        }else{
            return '';
        }

    }
}
if (!function_exists('getWeek')){
    /**
     * 获取当日周几
     * @author Yuanhang Liu & Xiaoyun Liu
     * @param $birthday 2020-10-14 00:48
     * @return string
     */
    function getWeek($date){

        $weekarray=array("周日","周一","周二","周三","周四","周五","周六");
        $weekday['week'] = $weekarray[date("w",strtotime($date))];
        $weekday['flag'] = date("w",strtotime($date));
        return $weekday ;
    }
}

//发送短信
if (!function_exists('send_sms')) {
    function send_sms($phone, $templateKey, $templateParam = [])
    {
        $sms_config = config('config.aly_sms');
        //是否启用https
        $security = false;
        $params = [];
        $params["PhoneNumbers"] = $phone;
        $params["SignName"] = $sms_config['sign_name'];
        $params["TemplateCode"] = $sms_config[$templateKey];
        $params['TemplateParam'] = $templateParam;

        if (is_array($params["TemplateParam"])) {
            $params["TemplateParam"] = json_encode($params["TemplateParam"], JSON_UNESCAPED_UNICODE);
        }

        $content = aly_sm_request(
            $sms_config['access_key'],
            $sms_config['access_secret'],
            "dysmsapi.aliyuncs.com",
            array_merge($params, array(
                "RegionId" => "cn-hangzhou",
                "Action" => "SendSms",
                "Version" => "2017-05-25",
            )),
            $security
        );

        return $content;
    }
}

if (!function_exists('aly_sm_request')) {
    function aly_sm_request($accessKeyId, $accessKeySecret, $domain, $params, $security = false, $method = 'POST')
    {
        $apiParams = array_merge(array(
            "SignatureMethod" => "HMAC-SHA1",
            "SignatureNonce" => uniqid(mt_rand(0, 0xffff), true),
            "SignatureVersion" => "1.0",
            "AccessKeyId" => $accessKeyId,
            "Timestamp" => gmdate("Y-m-d\TH:i:s\Z"),
            "Format" => "JSON",
        ), $params);
        ksort($apiParams);

        $sortedQueryStringTmp = "";
        foreach ($apiParams as $key => $value) {
            $sortedQueryStringTmp .= "&" . aly_sms_encode($key) . "=" . aly_sms_encode($value);
        }

        $stringToSign = "${method}&%2F&" . aly_sms_encode(substr($sortedQueryStringTmp, 1));

        $sign = base64_encode(hash_hmac("sha1", $stringToSign, $accessKeySecret . "&", true));

        $signature = aly_sms_encode($sign);

        $url = ($security ? 'https' : 'http') . "://{$domain}/";

        try {
            $content = aly_sms_fetch_content($url, $method, "Signature={$signature}{$sortedQueryStringTmp}");

            return json_decode($content, true);
        } catch (Exception $e) {
            return false;
        }
    }
}

if (!function_exists('aly_sms_encode')) {
    function aly_sms_encode($str)
    {
        $res = urlencode($str);
        $res = preg_replace("/\+/", "%20", $res);
        $res = preg_replace("/\*/", "%2A", $res);
        $res = preg_replace("/%7E/", "~", $res);
        return $res;
    }
}

if (!function_exists('aly_sms_fetch_content')) {
    function aly_sms_fetch_content($url, $method, $body)
    {
        $ch = curl_init();

        if ($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, 1);//post提交方式
            curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        } else {
            $url .= '?' . $body;
        }

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            "x-sdk-client" => "php/2.0.0"
        ));

        if (substr($url, 0, 5) == 'https') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }

        $rtn = curl_exec($ch);

        if ($rtn === false) {
            // 大多由设置等原因引起，一般无法保障后续逻辑正常执行，
            // 所以这里触发的是E_USER_ERROR，会终止脚本执行，无法被try...catch捕获，需要用户排查环境、网络等故障
            trigger_error("[CURL_" . curl_errno($ch) . "]: " . curl_error($ch), E_USER_ERROR);
        }
        curl_close($ch);

        return $rtn;
    }
}

    if (!function_exists('getDateFromList')) {
        /**
         * 获取指定日期段内每一天的日期
         * @param  Date  $startdate 开始日期
         * @param  Date  $enddate   结束日期
         * @return Array
         */
        function getDateFromList($start,$end){
            $stimestamp = strtotime($start);
            $etimestamp = strtotime($end);
            // 计算日期段内有多少天
            $days = ($etimestamp-$stimestamp)/86400+1;
            // 保存每天日期
            $arr = [];
            for($i=0;$i<$days;$i++){
                $arr[] = date('Y-m-d',$stimestamp+(86400*$i));
            }
            return $arr;


        }

    }

    if (!function_exists('numDays')){
        /**
         * 计算日期到现在多天天
         * @param $date
         * @return float
         */
        function numDays($date){
            $Date_List_a1=explode("-",date('Y-m-d',time()));
            $Date_List_a2=explode("-",$date);
            $d1=mktime(0,0,0,$Date_List_a1[1],$Date_List_a1[2],$Date_List_a1[0]);
            $d2=mktime(0,0,0,$Date_List_a2[1],$Date_List_a2[2],$Date_List_a2[0]);
            $Days=round(($d1-$d2)/3600/24);
            return $Days;
        }
    }






//检测重复请求 超过就禁止访问 有用户flag就针对用户flag 没有flag就针对ip地址(ip的话注意反代情况，可能每个用户请求的ip都是反代服务器的ip,当然可以配置一波反代服务器使得业务服务器获取到真实用户ip) 最小只能设置1s一次请求 不支持1s以下 如果开启了redis可以改写支持毫秒级的方法
if (!function_exists('check_repeat_request')) {
    function check_repeat_request($time, $limit, $flag = '')
    {
        $action = request()->getPathInfo();
        if (!empty($flag)){
            $key = $action.$flag;
        }
        else {
            $ip = request()->ip();
            $key = $action.$ip;
        }

        $time = $time < 1 ? 1 : $time;
        $time = round($time);
        if (Cache::has($key)){
            Cache::increment($key);
            $count = Cache::get($key);
            if($count > $limit){
                exit_out(null, 11003, '操作过于频繁，请稍后重试～');
            }
        }
        else {
            Cache::set($key, 1, $time);
        }

        return true;
    }
}

//随机生成验证码
if (!function_exists('generate_code')) {
    function generate_code($length = 6)
    {
        $min = pow(10, ($length - 1));
        $max = pow(10, $length) - 1;
        return rand($min, $max);
    }
}

if (!function_exists('object_array')) {
    function object_array($array) {
        if(is_object($array)) {
            $array = (array)$array;
        }
        if(is_array($array)) {
            foreach($array as $key=>$value) {
                $array[$key] = object_array($value);
            }
        }
        return $array;
    }
}

if (!function_exists('sechedule_timeperiod')) {
    function sechedule_timeperiod()
    {
        $schedule_config = SystemConfig::get('docter_config');
        $times[] = TimePeriod::where('start_time_period','>=',$schedule_config['morning_start'])->where('end_time_period','<=',$schedule_config['morning_end'])->pluck('id')->toArray();
        $times[] = TimePeriod::where('start_time_period','>=',$schedule_config['afternoon_start'])->where('end_time_period','<=',$schedule_config['afternoon_end'])->pluck('id')->toArray();
        $times[] = TimePeriod::where('start_time_period','>=',$schedule_config['evening_start'])->where('end_time_period','<=',$schedule_config['evening_end'])->pluck('id')->toArray();

        return $times;
    }
}

if (!function_exists('apiReturn')) {
    function apiReturn($code,$msg ='', $data ='') {
        return json_encode(['code'=>$code,'msg'=>$msg,'data'=>$data]);
    }
}


if (!function_exists('getDateFromList')) {
    /**
     * 获取指定日期段内每一天的日期
     * @param  Date  $startdate 开始日期
     * @param  Date  $enddate   结束日期
     * @return Array
     */
    function getDateFromList($start,$end){
        $stimestamp = strtotime($start);
        $etimestamp = strtotime($end);
        // 计算日期段内有多少天
        $days = ($etimestamp-$stimestamp)/86400+1;
        // 保存每天日期
        $arr = [];
        for($i=0;$i<$days;$i++){
            $arr[] = date('Y-m-d',$stimestamp+(86400*$i));
        }
        return $arr;


    }

}

if (!function_exists('numDays')){
    /**
     * 计算日期到现在多天天
     * @param $date
     * @return float
     */
    function numDays($date){
        $Date_List_a1=explode("-",date('Y-m-d',time()));
        $Date_List_a2=explode("-",$date);
        $d1=mktime(0,0,0,$Date_List_a1[1],$Date_List_a1[2],$Date_List_a1[0]);
        $d2=mktime(0,0,0,$Date_List_a2[1],$Date_List_a2[2],$Date_List_a2[0]);
        $Days=round(($d1-$d2)/3600/24);
        return $Days;
    }
}
