| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969 | <?phpuse think\Container;use think\Response;use think\facade\Lang;use think\facade\Queue;use think\facade\Cache;use core\util\Snowflake;use app\service\core\upload\CoreImageService;use app\service\core\sys\CoreSysConfigService;// 应用公共文件/** * 接口操作成功,返回信息 * @param array|string $msg * @param array|string|bool|null $data * @param int $code * @param int $http_code * @return Response */function success($msg = 'SUCCESS', $data = [], int $code = 1, int $http_code = 200): Response{    if (is_array($msg)) {        $data = $msg;        $msg = 'SUCCESS';    }    return Response::create([ 'data' => $data, 'msg' => get_lang($msg), 'code' => $code ], 'json', $http_code);}/** * 接口操作失败,返回信息 * @param $msg * @param array|null $data * @param int $code * @param int $http_code * @return Response */function fail($msg = 'FAIL', ?array $data = [], int $code = 0, int $http_code = 200) : Response{    if (is_array($msg)) {        $data = $msg;        $msg = 'FAIL';    }    return Response::create([ 'data' => $data, 'msg' => get_lang($msg), 'code' => $code ], 'json', $http_code);}/** * 自动侦测语言并转化 * @param $str * @return mixed */function get_lang($str){    return Lang::get($str);}/** * 把返回的数据集转换成Tree * @param $list 要转换的数据集 * @param string $pk * @param string $pid * @param string $child * @param int $root * @return array */function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = 'child', $root = 0){    // 创建Tree    $tree = array ();    if (is_array($list)) {        // 创建基于主键的数组引用        $refer = array ();        foreach ($list as $key => $data) {            $refer[ $data[ $pk ] ] =& $list[ $key ];        }        foreach ($list as $key => $data) {            // 判断是否存在parent            $parent_id = $data[ $pid ];            if ($root == $parent_id) {                $tree[] =& $list[ $key ];            } else {                if (isset($refer[ $parent_id ])) {                    $parent =& $refer[ $parent_id ];                    $parent[ $child ][] =& $list[ $key ];                }            }        }    }    return $tree;}/** * 生成加密密码 * @param $password * @param $salt  手动提供散列密码的盐值(salt)。这将避免自动生成盐值(salt)。,默认不填写将自动生成 * @return string */function create_password($password, $salt = ''){    return password_hash($password, PASSWORD_DEFAULT);}/** * 校验比对密码和加密密码是否一致 * @param $password * @param $hash * @return bool */function check_password($password, $hash){    if (!password_verify($password, $hash)) return false;    return true;}/** * 获取键对应的值 * @param array $array 源数组 * @param array $keys 要提取的键数组 * @param string $index 二维组中指定提取的字段(唯一) * @return array */function array_keys_search($array, $keys, $index = '', $is_sort = true){    if (empty($array))        return $array;    if (empty($keys))        return [];    if (!empty($index) && count($array) != count($array, COUNT_RECURSIVE))        $array = array_column($array, null, $index);    $list = array ();    foreach ($keys as $key) {        if (isset($array[ $key ])) {            if ($is_sort) {                $list[] = $array[ $key ];            } else {                $list[ $key ] = $array[ $key ];            }        }    }    return $list;}/** * @notes 删除目标目录 * @param $path * @param $delDir * @return bool|void */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;    }}/** * 获取一些公共的系统参数 * @param string|null $key * @return array|mixed */function system_name(?string $key = ''){    $params = [        'admin_token_name' => env('system.admin_token_name', 'token'),///todo !!! 注意  header参数  不能包含_ , 会自动转成 -        'api_token_name' => env('system.api_token_name', 'token'),        'admin_site_id_name' => env('system.admin_site_id_name', 'site-id'),        'api_site_id_name' => env('system.api_site_id_name', 'site-id'),        'channel_name' => env('system.channel_name', 'channel'),    ];    if (!empty($key)) {        return $params[ $key ];    } else {        return $params;    }}/** * 获取日期(默认不传参 获取当前日期) * @param int|null $time * @return string */function get_date_by_time(?int $time = null){    return date('Y-m-d h:i:s', $time);}function get_start_and_end_time_by_day($day = ''){    $date = $day ? : date('Y-m-d');    $day_start_time = strtotime($date);    //当天结束之间    $day_end_time = $day_start_time + 86400;    return [ $day_start_time, $day_end_time ];}/** * 路径转链接 * @param $path * @return string */function path_to_url($path){    return trim(str_replace(DIRECTORY_SEPARATOR, '/', $path), '.');}/** * 链接转化路径 * @param $url * @return string */function url_to_path($url){    if (str_contains($url, 'http://') || str_contains($url, 'https://')) return $url;//网络图片不必    return public_path() . trim(str_replace('/', DIRECTORY_SEPARATOR, $url));}/** * 获取本地文件的对外网络路径 * @param string $path * @return string */function get_file_url(string $path){    if (!$path) return '';    if (!str_contains($path, 'http://') && !str_contains($path, 'https://')) {        return request()->domain() . '/' . path_to_url($path);    } else {        return path_to_url($path);    }}/** * 新增队列工作 * @param $job * @param $data * @param $delay * @param $queue * @return bool */function create_job($job, $data = '', $delay = 0, $queue = null){    if ($delay > 0) {        $is_success = Queue::later($delay, $job, $data, $queue);    } else {        $is_success = Queue::push($job, $data, $queue);    }    if ($is_success !== false) {        return true;    } else {        return false;    }}/** * 获取插件对应资源文件(插件安装后获取) * @param $addon //插件名称 * @param $file_name //文件名称(包含resource文件路径) */function addon_resource($addon, $file_name){    return "addon/" . $addon . "/" . $file_name;}/** * 判断 文件/目录 是否可写(取代系统自带的 is_writeable 函数) * * @param string $file 文件/目录 * @return boolean */function is_write($file){    if (is_dir($file)) {        $dir = $file;        if ($fp = @fopen("$dir/test.txt", 'wb')) {            @fclose($fp);            @unlink("$dir/test.txt");            $writeable = true;        } else {            $writeable = false;        }    } else {        if ($fp = @fopen($file, 'ab+')) {            @fclose($fp);            $writeable = true;        } else {            $writeable = false;        }    }    return $writeable;}/** * 主要用于金额格式化(用于显示) * @param $number * @return int|mixed|string */function format_money($number){    if ($number == intval($number)) {        return intval($number);    } elseif ($number == sprintf('%.2f', $number)) {        return sprintf('%.2f', $number);    }    return $number;}/** * 金额浮点数格式化 * @param $number * @param $precision * @return float|int */function format_float_money($number, $precision = 2){    if ($precision > 0) {        return sprintf('%.' . $precision . 'f', floor($number * ( 10 ** $precision )) / ( 10 ** $precision ));    } else {        return sprintf('%.' . $precision . 'f', floor($number));    }}/** * 金额保留小数点后*位 * @param $number * @return float */function format_round_money($number){    return round($number, 2);}/** * 基础属性过滤(特殊字符..) * @param $string * @return void */function filter($string){    return $string;}/** * 生成编号 * @param string $prefix * @param string $tag 业务标识 例如member_id ... * @return string * @throws Exception */function create_no(string $prefix = '', string $tag = ''){    $data_center_id = 1;    $machine_id = 2;    $snowflake = new Snowflake($data_center_id, $machine_id);    $id = $snowflake->generateId();    return $prefix . date('Ymd') . $tag . $id;}/** * 多级目录不存在则创建 * @param $dir * @param $mode * @return bool */function mkdirs($dir, $mode = 0777){    if (str_contains($dir, '.')) $dir = dirname($dir);    if (is_dir($dir) || @mkdir($dir, $mode)) return true;    if (!mkdirs(dirname($dir), $mode)) return false;    return @mkdir($dir, $mode);}/** * 创建文件夹 * @param $dir * @param $mode * @return true */function mkdirs_or_notexist($dir, $mode = 0777){    if (!is_dir($dir) && !mkdir($dir, $mode, true) && !is_dir($dir)) {        throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));    }    return true;}/** * 删除缓存文件使用 * @param $dir */function rmdirs($dir){    $dh = opendir($dir);    while ($file = readdir($dh)) {        if ($file != "." && $file != "..") {            $fullpath = $dir . "/" . $file;            if (is_dir($fullpath)) {                rmdirs($fullpath);            } else {                unlink($fullpath);            }        }    }    closedir($dh);}/** * 获取唯一随机字符串 * @param int $len * @return string */function unique_random($len = 10){    $str = 'qwertyuiopasdfghjklzxcvbnmasdfgh';    str_shuffle($str);    return substr(str_shuffle($str), 0, $len);}/** * 校验事件结果 * @param $result * @return bool */function check_event_result($result){    if (empty($result) || is_array($result)) {        return true;    }    foreach ($result as $v) {        if (!$v) return false;    }    return true;}/** * 二维数组合并 * @param array $array1 * @param array $array2 * @return array */function array_merge2(array $array1, array $array2){    foreach ($array2 as $array2_k => $array2_v) {        if (array_key_exists($array2_k, $array1)) {            if (is_array($array2_v)) {                foreach ($array2_v as $array2_kk => $array2_vv) {                    if (array_key_exists($array2_kk, $array1[ $array2_k ])) {                        if (is_array($array2_vv)) {                            $array1[ $array2_k ][ $array2_kk ] = array_merge($array1[ $array2_k ][ $array2_kk ], $array2_vv);                        }                    } else {                        $array1[ $array2_k ][ $array2_kk ] = $array2_vv;                    }                }            } else {                $array1[ $array2_k ] = $array2_v;            }        } else {            $array1[ $array2_k ] = $array2_v;        }    }    return $array1;}/** * 通过目录获取文件结构1 * @param $dir * @return array */function get_files_by_dir($dir){    $dh = @opendir($dir);             //打开目录,返回一个目录流    $return = array ();    while ($file = @readdir($dh)) {     //循环读取目录下的文件        if ($file != '.' and $file != '..') {            $path = $dir . DIRECTORY_SEPARATOR . $file;     //设置目录,用于含有子目录的情况            if (is_dir($path)) {                $return[] = $file;            }        }    }    @closedir($dh);             //关闭目录流    return $return;               //返回文件}/** * 文件夹文件拷贝 * @param string $src 来源文件夹 * @param string $dst 目的地文件夹 * @param array $files 文件夹集合 * @param array $exclude_dirs 排除无需拷贝的文件夹 * @param array $exclude_files 排除无需拷贝的文件 * @return bool */function dir_copy(string $src = '', string $dst = '', &$files = [], $exclude_dirs = [], $exclude_files = []){    if (empty($src) || empty($dst)) {        return false;    }    if (!file_exists($src)) {        return false;    }    $dir = opendir($src);    dir_mkdir($dst);    while (false !== ( $file = readdir($dir) )) {        if (( $file != '.' ) && ( $file != '..' )) {            if (is_dir($src . '/' . $file)) {                // 排除目录                if (count($exclude_dirs) && in_array($file, $exclude_dirs)) continue;                dir_copy($src . '/' . $file, $dst . '/' . $file, $files);            } else {                // 排除文件                if (count($exclude_files) && in_array($file, $exclude_files)) continue;                copy($src . '/' . $file, $dst . '/' . $file);                $files[] = $dst . '/' . $file;            }        }    }    closedir($dir);    return true;}/** * 删除文件 * @param string $dst * @param array $dirs * @return bool */function dir_remove(string $dst = '', array $dirs = []){    if (empty($dirs) || empty($dst)) {        return false;    }    foreach ($dirs as $v) {        @unlink($dst . $v);    }    return true;}/** * 创建文件夹 * * @param string $path 文件夹路径 * @param int $mode 访问权限 * @param bool $recursive 是否递归创建 * @return bool */function dir_mkdir($path = '', $mode = 0777, $recursive = true){    clearstatcache();    if (!is_dir($path)) {        if (mkdir($path, $mode, $recursive)) {            return chmod($path, $mode);        } else {            throw new \core\exception\CommonException("目录{$path}创建失败请检查是否有足够的权限");        }    }    return true;}/** * 分割sql语句 * @param string $content sql内容 * @param bool $string 如果为真,则只返回一条sql语句,默认以数组形式返回 * @param array $replace 替换前缀,如:['my_' => 'me_'],表示将表前缀my_替换成me_ * @return array|string 除去注释之后的sql语句数组或一条语句 */function parse_sql($content = '', $string = false, $replace = []){    // 纯sql内容    $pure_sql = [];    // 被替换的前缀    $from = '';    // 要替换的前缀    $to = '';    // 替换表前缀    if (!empty($replace)) {        $to = current($replace);        $from = current(array_flip($replace));    }    if ($content != '') {        // 多行注释标记        $comment = false;        // 按行分割,兼容多个平台        $content = str_replace([ "\r\n", "\r" ], "\n", $content);        $content = explode("\n", trim($content));        // 循环处理每一行        foreach ($content as $line) {            // 跳过空行            if ($line == '') {                continue;            }            // 跳过以#或者--开头的单行注释            if (preg_match("/^(#|--)/", $line)) {                continue;            }            // 跳过以/**/包裹起来的单行注释            if (preg_match("/^\/\*(.*?)\*\//", $line)) {                continue;            }            // 多行注释开始            if (str_starts_with($line, '/*')) {                $comment = true;                continue;            }            // 多行注释结束            if (str_ends_with($line, '*/')) {                $comment = false;                continue;            }            // 多行注释没有结束,继续跳过            if ($comment) {                continue;            }            // 替换表前缀            if ($from != '') {                $line = str_replace('`' . $from, '`' . $to, $line);            }            // sql语句            $pure_sql[] = $line;        }        // 只返回一条语句        if ($string) {            return implode("", $pure_sql);        }        // 以数组形式返回sql语句        $pure_sql = implode("\n", $pure_sql);        $pure_sql = explode(";\n", $pure_sql);    }    return $pure_sql;}/** * 递归查询目录下所有文件 * @param $path * @param $data * @param $search * @return void */function search_dir($path, &$data, $search = ''){    if (is_dir($path)) {        $path .= DIRECTORY_SEPARATOR;        $fp = dir($path);        while ($file = $fp->read()) {            if ($file != '.' && $file != '..') {                search_dir($path . $file, $data, $search);            }        }        $fp->close();    }    if (is_file($path)) {        if ($search) $path = str_replace($search, '', $path);        $data[] = $path;    }}function remove_empty_dir($dirs){}/** * 获取文件地图 * @param $path * @param array $arr * @return array */function getFileMap($path, $arr = []){    if (is_dir($path)) {        $dir = scandir($path);        foreach ($dir as $file_path) {            if ($file_path != '.' && $file_path != '..') {                $temp_path = $path . '/' . $file_path;                if (is_dir($temp_path)) {                    $arr[ $temp_path ] = $file_path;                    $arr = getFileMap($temp_path, $arr);                } else {                    $arr[ $temp_path ] = $file_path;                }            }        }        return $arr;    }}/** * 如果不存在则写入缓存 * @param string|null $name * @param $value * @param $tag * @param $options * @return mixed|string */function cache_remember(string $name = null, $value = '', $tag = null, $options = null){    if (!empty($hit = Cache::get($name)))//可以用has        return $hit;    if ($value instanceof Closure) {        // 获取缓存数据        $value = Container::getInstance()->invokeFunction($value);    }    if (is_null($tag)) {        Cache::set($name, $value, $options[ 'expire' ] ?? null);    } else {        Cache::tag($tag)->set($name, $value, $options[ 'expire' ] ?? null);    }    return $value;}/** * 项目目录 * @return string */function project_path(){    return dirname(root_path()) . DIRECTORY_SEPARATOR;}/** * 图片转base64 * @param string $path * @param $is_delete 转换后是否删除原图 * @return string */function image_to_base64(string $path, $is_delete = false){    if (!file_exists($path)) return 'image not exist';    $mime = getimagesize($path)[ 'mime' ];    $image_data = file_get_contents($path);    // 将图片转换为 base64    $base64_data = base64_encode($image_data);    if ($is_delete) @unlink($path);    return "data:$mime;base64,$base64_data";}/** * 获取缩略图 * @param $site_id * @param $image * @param string $thumb_type * @param bool $is_throw_exception * @return mixed * @throws Exception */function get_thumb_images($site_id, $image, $thumb_type = 'all', bool $is_throw_exception = false){    return ( new CoreImageService() )->thumb($site_id, $image, $thumb_type, $is_throw_exception);}/** * 版本号转整数 例如1.0.0=001.000.000=001000000=1000000 * @param $version * @return int */function version_to_int($version){    $version_array = explode(".", $version);    $v1 = sprintf('%03s', (int) $version_array[ 0 ] ?? 0);    $v2 = sprintf('%03s', (int) $version_array[ 1 ] ?? 0);    $v3 = sprintf('%03s', (int) $version_array[ 2 ] ?? 0);    return (int) "{$v1}{$v2}{$v3}";}/** * 整数版本号转字符串例如 1000000=001000000=001.000.000=1.0.0 * @param int $ver * @return string */function version_to_string($ver){    if ($ver > 999) {        if ($ver > 999999) {            $ver .= "";            $v3 = (int) substr($ver, -3);            $v2 = (int) substr($ver, -6, 3);            $v1 = (int) substr($ver, 0, -6);        } else {            $ver .= "";            $v3 = (int) substr($ver, -3);            $v2 = (int) substr($ver, 0, -3);            $v1 = 0;        }    } else {        $v3 = $ver;        $v2 = 0;        $v1 = 0;    }    return "{$v1}.{$v2}.{$v3}";}/** * 检测文件是否是本地图片 * @param string $file_path * @return void */function check_file_is_remote(string $file_path){    return str_contains($file_path, 'https://') || str_contains($file_path, 'http://') || str_contains($file_path, '.com');}/** * 文件拷贝 * @param string $source_file * @param string $to_file * @return void */function file_copy(string $source_file, string $to_file){    if (!file_exists($source_file)) return false;    // 检查目标文件是否存在    if (!file_exists($to_file)) {        // 创建目录        $directory = dirname($to_file);        if (!file_exists($directory)) {            mkdir($directory, 0777, true);        }    }    if (copy($source_file, $to_file)) {        return true;    } else {        return false;    }}/** * 创建并生成二维码 * @param $url * @param $site_id * @param $dir * @param $file_path * @param $channel * @param $size * @return string */function qrcode($url, $page, $data, $site_id, $dir = '', $channel = 'h5', $style = [ 'is_transparent' => true ], $outfile = true){    $site_id = 0;    if ($outfile) {        $dir = $dir ?: 'upload' . '/' . 'qrcode' . '/' . $site_id;//二维码默认存储位置        if (!is_dir($dir) && !mkdir($dir, 0777, true) && !is_dir($dir)) {            throw new \RuntimeException(sprintf('Directory "%s" was not created', $dir));        }        $file_path = md5($url . $page . serialize($data) . serialize($style) . $channel);        $path = $dir . '/' . $file_path . '.png';        if (file_exists($path)) {            return $path;        }    }    $result = array_values(array_filter(event('GetQrcodeOfChannel', [        'filepath' => $path ?? '',        'url' => $url,        'page' => $page,        'data' => $data,        'site_id' => $site_id,        'channel' => $channel,        'outfile' => $outfile    ])));    if (!empty($result[ 0 ])) {        $path = $result[ 0 ];    }//    if(!empty($style)){//        $is_transparent = $style['is_transparent'] ?? false;//是否透明//        $color = $style['color'] ?? '#000';//颜色//        $bg_color = $style['bg_color'] ?? '#FFF';//        //将二维码背景变透明//        $resource = imagecreatefrompng($path);//        @unlink($path);//        if($is_transparent){//            $bgcolor = imagecolorallocate($resource, 255, 255, 255);//            imagefill($resource, 0, 0, $bgcolor);//            imagecolortransparent($resource, $bgcolor);//        }//        // 设置彩色二维码的颜色//        $color = imagecolorallocate($resource, 229, 39, 21); // 红色//        // 修改二维码的像素颜色//        imagesetpixel($resource, 10, 10, $color);//        imagepng($resource,$path);//    }    return $path;}/** * 获取海报 * @param int $site_id * @param $id * @param $type * @param array $param * @param string $channel * @param bool $is_throw_exception * @return string|void */function poster(int $site_id, $id, $type, array $param = [], string $channel = '', bool $is_throw_exception = true){    return ( new \app\service\core\poster\CorePosterService() )->get($site_id, $id, $type, $param, $channel, $is_throw_exception);}/** * 获取站点插件 * @return array */function get_site_addons($site_id = 0) : array{    $addons = $site_id ? Cache::get("local_install_addons_{$site_id}") : Cache::get("local_install_addons");    return is_null($addons) ? [] : $addons;}function get_wap_domain(){    $wap_url = ( new CoreSysConfigService() )->getSceneDomain()[ 'wap_url' ];    return $wap_url;}/** * $str为要进行截取的字符串,$length为截取长度(汉字算一个字,字母算半个字 * @param $str * @param int $length * @param bool $is_need_apostrophe * @return string */function str_sub($str, $length = 10, $is_need_apostrophe = true){    return mb_substr($str, 0, $length, 'UTF-8') . ( $is_need_apostrophe ? '...' : '' );}
 |