<?php
// 应用公共文件
use app\common\service\FileService;
use JPush\Client;
use think\helper\Str;

/**
 * @notes 生成密码加密密钥
 * @param string $plaintext
 * @param string $salt
 * @return string
 * @author 段誉
 * @date 2021/12/28 18:24
 */
function create_password(string $plaintext, string $salt) : string
{
    return md5($salt . md5($plaintext . $salt));
}


/**
 * @notes 随机生成token值
 * @param string $extra
 * @return string
 * @author 段誉
 * @date 2021/12/28 18:24
 */
function create_token(string $extra = '') : string
{
    $salt = env('project.unique_identification', 'likeadmin');
    $encryptSalt = md5( $salt . uniqid());
    return md5($salt . $extra . time() . $encryptSalt);
}


/**
 * @notes 截取某字符字符串
 * @param $str
 * @param string $symbol
 * @return string
 * @author 段誉
 * @date 2021/12/28 18:24
 */
function substr_symbol_behind($str, $symbol = '.') : string
{
    $result = strripos($str, $symbol);
    if ($result === false) {
        return $str;
    }
    return substr($str, $result + 1);
}


/**
 * @notes 对比php版本
 * @param string $version
 * @return bool
 * @author 段誉
 * @date 2021/12/28 18:27
 */
function compare_php(string $version) : bool
{
    return version_compare(PHP_VERSION, $version) >= 0 ? true : false;
}


/**
 * @notes 检查文件是否可写
 * @param string $dir
 * @return bool
 * @author 段誉
 * @date 2021/12/28 18:27
 */
function check_dir_write(string $dir = '') : bool
{
    $route = root_path() . '/' . $dir;
    return is_writable($route);
}


/**
 * 多级线性结构排序
 * 转换前:
 * [{"id":1,"pid":0,"name":"a"},{"id":2,"pid":0,"name":"b"},{"id":3,"pid":1,"name":"c"},
 * {"id":4,"pid":2,"name":"d"},{"id":5,"pid":4,"name":"e"},{"id":6,"pid":5,"name":"f"},
 * {"id":7,"pid":3,"name":"g"}]
 * 转换后:
 * [{"id":1,"pid":0,"name":"a","level":1},{"id":3,"pid":1,"name":"c","level":2},{"id":7,"pid":3,"name":"g","level":3},
 * {"id":2,"pid":0,"name":"b","level":1},{"id":4,"pid":2,"name":"d","level":2},{"id":5,"pid":4,"name":"e","level":3},
 * {"id":6,"pid":5,"name":"f","level":4}]
 * @param array $data 线性结构数组
 * @param string $symbol 名称前面加符号
 * @param string $name 名称
 * @param string $id_name 数组id名
 * @param string $parent_id_name 数组祖先id名
 * @param int $level 此值请勿给参数
 * @param int $parent_id 此值请勿给参数
 * @return array
 */
function linear_to_tree($data, $sub_key_name = 'sub', $id_name = 'id', $parent_id_name = 'pid', $parent_id = 0)
{
    $tree = [];
    foreach ($data as $row) {
        if ($row[$parent_id_name] == $parent_id) {
            $temp = $row;
            $child = linear_to_tree($data, $sub_key_name, $id_name, $parent_id_name, $row[$id_name]);
            if ($child) {
                $temp[$sub_key_name] = $child;
            }
            $tree[] = $temp;
        }
    }
    return $tree;
}


/**
 * @notes 删除目标目录
 * @param $path
 * @param $delDir
 * @return bool|void
 * @author 段誉
 * @date 2022/4/8 16:30
 */
function del_target_dir($path, $delDir)
{
    //没找到,不处理
    if (!file_exists($path)) {
        return false;
    }

    //打开目录句柄
    $handle = opendir($path);
    if ($handle) {
        while (false !== ($item = readdir($handle))) {
            if ($item != "." && $item != "..") {
                if (is_dir("$path/$item")) {
                    del_target_dir("$path/$item", $delDir);
                } else {
                    unlink("$path/$item");
                }
            }
        }
        closedir($handle);
        if ($delDir) {
            return rmdir($path);
        }
    } else {
        if (file_exists($path)) {
            return unlink($path);
        }
        return false;
    }
}


/**
 * @notes 下载文件
 * @param $url
 * @param $saveDir
 * @param $fileName
 * @return string
 * @author 段誉
 * @date 2022/9/16 9:53
 */
function download_file($url, $saveDir, $fileName)
{
    if (!file_exists($saveDir)) {
        mkdir($saveDir, 0775, true);
    }
    $fileSrc = $saveDir . $fileName;
    file_exists($fileSrc) && unlink($fileSrc);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    $file = curl_exec($ch);
    curl_close($ch);
    $resource = fopen($fileSrc, 'a');
    fwrite($resource, $file);
    fclose($resource);
    if (filesize($fileSrc) == 0) {
        unlink($fileSrc);
        return '';
    }
    return $fileSrc;
}


/**
 * @notes 去除内容图片域名
 * @param $content
 * @return array|string|string[]
 * @author 段誉
 * @date 2022/9/26 10:43
 */
function clear_file_domain($content)
{
    $fileUrl = FileService::getFileUrl();
    return str_replace($fileUrl, '/', $content);
}


/**
 * @notes 设置内容图片域名
 * @param $content
 * @return array|string|string[]|null
 * @author 段誉
 * @date 2022/9/26 10:43
 */
function get_file_domain($content)
{
    $preg = '/(<img .*?src=")[^https|^http](.*?)(".*?>)/is';
    $fileUrl = FileService::getFileUrl();
    return preg_replace($preg, "\${1}$fileUrl\${2}\${3}", $content);
}


/**
 * @notes uri小写
 * @param $data
 * @return array|string[]
 * @author 段誉
 * @date 2022/7/19 14:50
 */
function lower_uri($data)
{
    if (!is_array($data)) {
        $data = [$data];
    }
    return array_map(function ($item) {
        return strtolower(Str::camel($item));
    }, $data);
}


/**
 * @notes 获取无前缀数据表名
 * @param $tableName
 * @return mixed|string
 * @author 段誉
 * @date 2022/12/12 15:23
 */
function get_no_prefix_table_name($tableName)
{
    $tablePrefix = config('database.connections.mysql.prefix');
    $prefixIndex = strpos($tableName, $tablePrefix);
    if ($prefixIndex !== 0 || $prefixIndex === false) {
        return $tableName;
    }
    $tableName = substr_replace($tableName, '', 0, strlen($tablePrefix));
    return trim($tableName);
}


/**
 * @notes 生成编码
 * @param $table
 * @param $field
 * @param string $prefix
 * @param int $randSuffixLength
 * @param array $pool
 * @return string
 * @author 段誉
 * @date 2023/2/23 11:35
 */
function generate_sn($table, $field, $prefix = '', $randSuffixLength = 4, $pool = []) : string
{
    $suffix = '';
    for ($i = 0; $i < $randSuffixLength; $i++) {
        if (empty($pool)) {
            $suffix .= rand(0, 9);
        } else {
            $suffix .= $pool[array_rand($pool)];
        }
    }
    $sn = $prefix . date('YmdHis') . $suffix;
    if (app()->make($table)->where($field, $sn)->find()) {
        return generate_sn($table, $field, $prefix, $randSuffixLength, $pool);
    }
    return $sn;
}


/**
 * @notes 格式化金额
 * @param $float
 * @return int|mixed|string
 * @author 段誉
 * @date 2023/2/24 11:20
 */
function format_amount($float)
{
    if ($float == intval($float)) {
        return intval($float);
    } elseif ($float == sprintf('%.1f', $float)) {
        return sprintf('%.1f', $float);
    }
    return $float;
}

/**
 * 间隔时间段格式化
 * @param int $time 时间戳
 * @param string $format 格式 【d:显示到天 i显示到分钟 s显示到秒】
 * @return string
 */
function countDays($a, $b = 0)
{
    if ($b == 0) {
        $b = date("Y-m-d");
    }
    $date_1 = $a;
    $date_2 = $b;
    $d1 = strtotime($date_1);
    $d2 = strtotime($date_2);
    $days = round(($d2 - $d1) / 3600 / 24);
    if ($days > 0) {
        return $days;
    } else {
        return 0;
    }
}

/**
 * 间隔时间段格式化
 * @param int $time 时间戳
 * @param string $format 格式 【d:显示到天 i显示到分钟 s显示到秒】
 * @return string
 */
function time_trans($time, $format = 'd')
{
    $now = time();
    $diff = $now - $time;
    if ($diff < 60) {
        return $diff . '秒前';
    } else if ($diff < 3600) {
        return floor($diff / 60) . '分钟前';
    } else if ($diff < 86400) {
        return floor($diff / 3600) . '小时前';
    }
    $yes_start_time = strtotime(date('Y-m-d 00:00:00', strtotime('-1 days'))); //昨天开始时间
    $yes_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-1 days'))); //昨天结束时间
    $two_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-2 days'))); //2天前结束时间
    $three_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-3 days'))); //3天前结束时间
    $four_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-4 days'))); //4天前结束时间
    $five_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-5 days'))); //5天前结束时间
    $six_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-6 days'))); //6天前结束时间
    $seven_end_time = strtotime(date('Y-m-d 23:59:59', strtotime('-7 days'))); //7天前结束时间

    if ($time > $yes_start_time && $time < $yes_end_time) {
        return '昨天';
    }

    if ($time > $yes_start_time && $time < $two_end_time) {
        return '1天前';
    }

    if ($time > $yes_start_time && $time < $three_end_time) {
        return '2天前';
    }

    if ($time > $yes_start_time && $time < $four_end_time) {
        return '3天前';
    }

    if ($time > $yes_start_time && $time < $five_end_time) {
        return '4天前';
    }

    if ($time > $yes_start_time && $time < $six_end_time) {
        return '5天前';
    }

    if ($time > $yes_start_time && $time < $seven_end_time) {
        return '6天前';
    }

    switch ($format) {
        case 'd':
            $show_time = date('Y-m-d', $time);
            break;
        case 'i':
            $show_time = date('Y-m-d H:i', $time);
            break;
        case 's':
            $show_time = date('Y-m-d H:i:s', $time);
            break;
    }
    return $show_time;
}

//获取url参数
function get_params($key = "")
{
    return \think\facade\Request::instance()->param($key);
}

/**
 * 返回json数据,用于接口
 * @param    integer    $code
 * @param    string     $msg
 * @param    array      $data
 * @param    string     $url
 * @param    integer    $httpCode
 * @param    array      $header
 * @param    array      $options
 * @return   json
 */
function to_assign($code = 0, $msg = "操作成功", $data = [], $url = '', $httpCode = 200, $header = [], $options = [])
{
    $res = ['code' => $code];
    $res['msg'] = $msg;
    $res['url'] = $url;
    if (is_object($data)) {
        $data = $data->toArray();
    }
    $res['data'] = $data;
    $response = \think\Response::create($res, "json", $httpCode, $header, $options);
    throw new \think\exception\HttpResponseException($response);
}

function get_login_admin($key = "")
{
//    $admin = request()->
    $session_admin = get_config('app.session_admin');
    if (\think\facade\Session::has($session_admin)) {
        $gougu_admin = \think\facade\Session::get($session_admin);
        if (!empty($key)) {
            if (isset($gougu_admin[$key])) {
                return $gougu_admin[$key];
            } else {
                return '';
            }
        } else {
            return $gougu_admin;
        }
    } else {
        return '';
    }
}

//读取文件配置
function get_config($key)
{
    return \think\facade\Config::get($key);
}

/**
 * 循环获取子级
 * @param $model
 * @param $id
 * @param $parentKey
 * @param $field
 * @return array
 */
function loopGetChild($model, $id, $parentKey = 'pid', $field = '*')
{
    static $result = [];
    $list = $model::where($parentKey, $id)->field($field)->select()->toArray();
    if ($list) {
        foreach ($list as $v) {
            $result[] = $v;
            loopGetChild($model, $v['id'], $parentKey, $field);
        }
    }
    return $result;
}

function append($data, $append, $key = 'id', $appendKey = 'append')
{
    $tmp = [];
    foreach ($append as $item) {
        $tmp[$item['id']] = $item;
    }
    foreach ($data as &$v) {
        $v[$appendKey] = $tmp[$v[$key]] ?? [];
    }
    return $data;
}

function curl_get($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    $result = json_decode($output,true);
    return $result;
}

function curl_post($url,$headers,$data) {
    //初始化curl
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_URL,$url);
    //设置获取的信息以文件流的形式返回,而不是直接输出。
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    //设置头文件的信息作为数据流输出
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    //设置为post方式请求
    curl_setopt($ch, CURLOPT_POST, 1);
    //添加参数
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    //设置header
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    //关闭请求资源
    $output = curl_exec($ch);
    curl_close($ch);
    return json_decode($output,true);
}

function push_message($reg_id,$message){
    //获取配置信息
    $jpush_config = config('app.jpush');
    $app_key= $jpush_config['app_key'];     //这是app密钥,填你自己的
    $master_secret= $jpush_config['master_secret'];    //这也是密钥,填你自己的
    //实例化
    $client = new Client($app_key,$master_secret);
    $pusher = $client->push();
    $pusher->setPlatform('all');
    $pusher->addRegistrationId($reg_id);
    $pusher->setNotificationAlert($message);
    try {
        $res = $pusher->send();
        return ['code'=>1,'msg'=>'','data'=>$res];
    } catch (\JPush\Exceptions\JPushException $e) {
        return ['code'=>0,'msg'=>$e->getMessage(),'data'=>[]];
    }
}