{$value}(); } } //日志内容 $log = [ $id, //管理员ID request()->ip(), //客户ip ceil(microtime() - (request()->time(true) * 1000)), //耗时(毫秒) request()->method(true), //请求类型 str_replace("/", "", request()->rootUrl()), //应用 request()->baseUrl(), //路由 json_encode(request()->param(), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),//请求参数 json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), //报错数据 ]; Log::write(implode("|", $log), $type); } catch (\Throwable $e) { } } } if (!function_exists('not_empty_check')) { /** * 非空验证 * @param $param * @return bool */ function not_empty_check($param) { if (is_array($param)) { return !(count($param) <= 0); } else { if ($param == '') { return false; } if ($param == null) { return false; } return true; } } } if (!function_exists('do_request')) { /** * CURL 请求接口 * @param string $url 请求地址 * @param array $data 请求参数 * @param array $header 请求头 * @param bool $post true:post请求 false:get请求 * @param bool $json post请求时 请求数据打包方式是否为json * @param int $format 数据打包为json格式时打包的格式值 来自json_encode * @param bool $form post请求时 请求数据是否为表单 同时为false时为http提交 优先级高于json * @return bool|false|string */ function do_request($url, $query, $data, $header = null, $post = true, $json = false, $format = 0, $form = false) { $curl = curl_init(); $url .= ('?' . http_build_query($query)); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); if ($post) { curl_setopt($curl, CURLOPT_POST, 1); if (!$json && !$form) { curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data)); } else if ($json && !$form) { curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data, $format)); } else { curl_setopt($curl, CURLOPT_POSTFIELDS, $data); } } curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); if ($header) { curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($curl, CURLOPT_HEADER, 0); } $result = curl_exec($curl); if (curl_errno($curl)) { return json_encode(['status' => curl_errno($curl), 'msg' => '请求失败']); } curl_close($curl); return $result; } } if (!function_exists('path_to_url')) { /** * 路径转url路径 * @param $path * @return string */ function path_to_url($path) { return trim(str_replace(DS, '/', $path), '.'); } } if (!function_exists('get_group_user')) { //所有下级 function get_group_user($id, $init = true, $members = null) { if ($init) { $us = User::column('spread_uid', 'uid'); $members = []; foreach ($us as $k => $v) { if ($v > 0) $members[$v][] = $k; } $id = [$id]; } $arr = array(); foreach ($id as $v) { $child = $members[$v] ?? []; $arr = array_merge($arr, $child); } if (count($arr)) { return array_merge($arr, get_group_user($arr, false, $members)); } else { return $arr; } } } if (!function_exists('sys_config')) { /** * 获取系统单个配置 * @param string $name * @param mixed $default * @param bool $cache * @return string|array */ function sys_config(string $name, $default = '', bool $cache = false) { if (empty($name)) return $default; $config = app('sysConfig')->get($name, $default, $cache); if (is_string($config)) $config = trim($config); if ($config === '' || $config === false) { return $default; } else { return $config; } } } if (!function_exists('store_config')) { /** * 获取系统单个配置 * @param string $name * @param int $store_id * @param mixed $default * @param bool $cache * @return string */ function store_config(string $name, int $store_id, $default = '', bool $cache = false) { if (empty($name)) return $default; $config = app('sysConfig')->setStore($store_id)->get($name, $default, $cache); if (is_string($config)) $config = trim($config); if ($config === '' || $config === false) { return $default; } else { return $config; } } } if (!function_exists('check_phone')) { /** * 手机号验证 * @param $phone * @return false|int */ function check_phone($phone) { return preg_match("/^1[3456789]\d{9}$/", $phone); } } if (!function_exists('check_mail')) { /** * 邮箱验证 * @param $mail * @return false|int */ function check_mail($mail) { if (filter_var($mail, FILTER_VALIDATE_EMAIL)) { return true; } else { return false; } } } if (!function_exists('aj_captcha_check_one')) { /** * 验证滑块1次验证 * @param string $token * @param string $pointJson * @return bool */ function aj_captcha_check_one(string $captchaType, string $token, string $pointJson) { aj_get_serevice($captchaType)->check($token, $pointJson); return true; } } if (!function_exists('aj_captcha_check_two')) { /** * 验证滑块2次验证 * @param string $token * @param string $pointJson * @return bool */ function aj_captcha_check_two(string $captchaType, string $captchaVerification) { aj_get_serevice($captchaType)->verificationByEncryptCode($captchaVerification); return true; } } if (!function_exists('aj_captcha_create')) { /** * 创建验证码 * @return array */ function aj_captcha_create(string $captchaType) { return aj_get_serevice($captchaType)->get(); } } if (!function_exists('aj_get_serevice')) { /** * @param string $captchaType * @return ClickWordCaptchaService|BlockPuzzleCaptchaService */ function aj_get_serevice(string $captchaType) { $config = \think\facade\Config::get('ajcaptcha'); switch ($captchaType) { case "clickWord": $service = new ClickWordCaptchaService($config); break; case "blockPuzzle": $service = new BlockPuzzleCaptchaService($config); break; default: throw new ValidateException('captchaType参数不正确!'); } return $service; } } if (!function_exists('sort_list_tier')) { /** * 分级排序 * @param $data * @param int $pid * @param string $field * @param string $pk * @param string $html * @param int $level * @param bool $clear * @return array */ function sort_list_tier($data, $pid = 0, $field = 'pid', $pk = 'id', $html = '|-----', $level = 1, $clear = true) { static $list = []; if ($clear) $list = []; foreach ($data as $k => $res) { if ($res[$field] == $pid) { $res['html'] = str_repeat($html, $level); $list[] = $res; unset($data[$k]); sort_list_tier($data, $res[$pk], $field, $pk, $html, $level + 1, false); } } return $list; } } if (!function_exists('get_tree_children')) { /** * 获取树状结构子集 */ function get_tree_children($data, $id = 0, $field = 'id', $pid = 'pid', $init = true) { static $children; if ($init) { $children = []; foreach ($data as $v) { $children[$v[$pid]][] = $v; } } $arr = ($children[$id] ?? []); foreach ($arr as &$v) { $v['children'] = get_tree_children($data, $v[$field], $field, $pid, false); } return $arr; } } if (!function_exists('set_file_url')) { /** * @param $file * @return mixed|string */ function set_file_url($file) { if (!is_array($file)) { $file = [$file]; } foreach ($file as &$v) { if (strpos($v, '://') === false) { $v = rtrim(sys_config('site_url', ''), '/') . '/' . ltrim($v, '/'); } } return $file; } } if (!function_exists('check_link')) { /** * @param $file * @return mixed|string */ function check_link($url) { $ch = curl_init(); try { curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); $contents = curl_exec($ch); if (preg_match("/404/", $contents)) return false; if (preg_match("/403/", $contents)) return false; return true; } catch (\Exception $e) { return false; } } } if (!function_exists('filter_emoji')) { // 过滤掉emoji表情 function filter_emoji($str) { return preg_replace_callback( //执行一个正则表达式搜索并且使用一个回调进行替换 '/./u', function (array $match) { return strlen($match[0]) >= 4 ? '' : $match[0]; }, $str); } } if (!function_exists('getFileHeaders')) { /** * 获取文件大小头部信息 * @param string $url * @param $isData * @return array */ function getFileHeaders(string $url, $isData = true) { stream_context_set_default(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]); $header['size'] = 0; $header['type'] = 'image/jpeg'; if (!$isData) { return $header; } try { $headerArray = get_headers(str_replace('\\', '/', $url), true); if (!isset($headerArray['Content-Length'])) { $header['size'] = 0; } else { if (is_array($headerArray['Content-Length']) && count($headerArray['Content-Length']) == 2) { $header['size'] = $headerArray['Content-Length'][1]; } else { $header['size'] = $headerArray['Content-Length'] ?? 0; } } if (!isset($headerArray['Content-Type'])) { $header['type'] = 'image/jpeg'; } else { if (is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2) { $header['type'] = $headerArray['Content-Type'][1]; } else { $header['type'] = $headerArray['Content-Type'] ?? 'image/jpeg'; } } } catch (\Exception $e) { } return $header; } } if (!function_exists('formatFileSize')) { /** * 格式化文件大小 * @param $size * @return mixed|string|null */ function formatFileSize($size) { if (!$size) { return '0KB'; } try { $toKb = 1024; $toMb = $toKb * 1024; $toGb = $toMb * 1024; if ($size >= $toGb) { return round($size / $toGb, 2) . 'GB'; } elseif ($size >= $toMb) { return round($size / $toMb, 2) . 'MB'; } elseif ($size >= $toKb) { return round($size / $toKb, 2) . 'KB'; } else { return $size . 'B'; } } catch (Exception $e) { return '0KB'; } } } if (!function_exists('get_image_thumb')) { /** * 获取缩略图 * @param $filePath * @param string $type all|big|mid|small * @param bool $is_remote_down * @return mixed|string|string[] */ function get_image_thumb($filePath, string $type = 'all', bool $is_remote_down = false) { if (!$filePath || !is_string($filePath) || strpos($filePath, '?') !== false) return $filePath; try { $arr = explode('.', $filePath); $ext_name = trim($arr[count($arr) - 1]); if (!in_array($ext_name, ['png', 'jpg', 'jpeg'])) { return $filePath; } $upload = UploadService::getOssInit($filePath, $is_remote_down); $data = $upload->thumb('', $type); $image = $type == 'all' ? $data : $data[$type] ?? $filePath; } catch (\Throwable $e) { $image = $filePath; // throw new ValidateException($e->getMessage()); Log::error('获取缩略图失败,原因:' . $e->getMessage() . '----' . $e->getFile() . '----' . $e->getLine() . '----' . $filePath); } $data = parse_url($image); if (!isset($data['host']) && (substr($image, 0, 2) == './' || substr($image, 0, 1) == '/')) {//不是完整地址 $image = sys_config('site_url') . $image; } //请求是https 图片是http 需要改变图片地址 if (strpos(request()->domain(), 'https:') !== false && strpos($image, 'https:') === false) { $image = str_replace('http:', 'https:', $image); } return $image; } } if (!function_exists('get_thumb_water')) { /** * 处理数组获取缩略图、水印 * @param $list * @param string $type * @param array|string[] $field 1、['image','images'] type 取值参数:type 2、['small'=>'image','mid'=>'images'] type 取field数组的key * @param bool $is_remote_down * @return array|mixed|string|string[] */ function get_thumb_water($list, string $type = 'small', array $field = ['image'], bool $is_remote_down = false) { if (!$list || !$field) return $list; $baseType = $type; $data = $list; if (is_string($list)) { $field = [$type => 'image']; $data = ['image' => $list]; } if (is_array($data)) { foreach ($field as $type => $key) { if (is_integer($type)) {//索引数组,默认type $type = $baseType; } //一维数组 if (isset($data[$key])) { if (is_array($data[$key])) { $path_data = []; foreach ($data[$key] as $k => $path) { $path_data[] = get_image_thumb($path, $type, $is_remote_down); } $data[$key] = $path_data; } else { $data[$key] = get_image_thumb($data[$key], $type, $is_remote_down); } } else { foreach ($data as &$item) { if (!isset($item[$key])) continue; if (is_array($item[$key])) { $path_data = []; foreach ($item[$key] as $k => $path) { $path_data[] = get_image_thumb($path, $type, $is_remote_down); } $item[$key] = $path_data; } else { $item[$key] = get_image_thumb($item[$key], $type, $is_remote_down); } } } } } return is_string($list) ? ($data['image'] ?? '') : $data; } } if (!function_exists('make_path')) { /** * 上传路径转化,默认路径 * @param $path * @param int $type * @param bool $force * @return string * @throws Exception */ function make_path($path, int $type = 2, bool $force = false) { $path = DS . ltrim(rtrim($path)); switch ($type) { case 1: $path .= DS . date('Y'); break; case 2: $path .= DS . date('Y') . DS . date('m'); break; case 3: $path .= DS . date('Y') . DS . date('m') . DS . date('d'); break; } try { if (is_dir(app()->getRootPath() . 'public' . DS . 'uploads' . $path) == true || mkdir(app()->getRootPath() . 'public' . DS . 'uploads' . $path, 0777, true) == true) { return trim(str_replace(DS, '/', $path), '.'); } else return ''; } catch (Exception $e) { if ($force) throw new Exception($e->getMessage()); return '无法创建文件夹,请检查您的上传目录权限:' . app()->getRootPath() . 'public' . DS . 'uploads' . DS . 'attach' . DS; } } } if (!function_exists('verify_domain')) { /** * @param $url * @return false|string */ function verify_domain($url) { if (!$url) return false; if (strpos($url, 'http') === false) return false; return rtrim($url, '/'); } } if (!function_exists('password')) { /** * @param $string * @param null $salt * @return array * @throws Exception */ function password($string, $salt = null) { if (!$salt) $salt = bin2hex(random_bytes(6)); return [md5(md5($string) . $salt), $salt]; } } if (!function_exists('parseName')) { /** * 字符串命名风格转换 * type 0 将 Java 风格转换为 C 的风格 1 将 C 风格转换为 Java 的风格 * @access public * @param string $name 字符串 * @param integer $type 转换类型 * @param bool $ucfirst 首字母是否大写(驼峰规则) * @return string */ function parseName($name, $type = 0, $ucfirst = true) { if ($type) { $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) { return strtoupper($match[1]); }, $name ?? ''); return $ucfirst ? ucfirst($name) : lcfirst($name); } return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_")); } } if (!function_exists('check_card')) { function check_card($idCard) { // 去除空格 $idCard = trim($idCard); // 18位身份证号码正则表达式 $pattern = '/^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[0-9Xx]$/'; if (!preg_match($pattern, $idCard)) { return false; } // 校验码验证 $weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; $checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; $sum = 0; for ($i = 0; $i < 17; $i++) { $sum += intval($idCard[$i]) * $weights[$i]; } $checkCodeIndex = $sum % 11; $expectedCheckCode = $checkCodes[$checkCodeIndex]; return strtoupper($idCard[17]) === $expectedCheckCode; } } if (!function_exists('check_password')) { function check_password($value) { // 正则表达式:至少6位,最多18位,包含大小写字母、数字和特殊字符 $pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{6,18}$/'; return preg_match($pattern, $value) === 1; } } if (!function_exists('check_trade_password')) { function check_trade_password($value) { return preg_match('/^\d{6}$/', $value) === 1; } } if (!function_exists('check_sms_captcha')) { function check_sms_captcha($phone, $type, $code) { $verifyCode = CacheService::get('code_' . $phone . '_' . $type); if (!$verifyCode) throw new AuthException('请先获取验证码'); $verifyError = (int)CacheService::get('code_error_' . $phone . '_' . $type, 0); if ($verifyError >= 10) { throw new AuthException('错误次数过多,请稍后再试'); } $verifyCode = substr($verifyCode, 0, 6); if ($verifyCode != $code) { CacheService::set('code_error_' . $phone . '_' . $type, $verifyError + 1, 180); throw new AuthException('验证码错误'); } CacheService::delete('code_' . $phone . '_' . $type); CacheService::delete('code_error_' . $phone . '_' . $type); } } if (!function_exists('random_string')) { function random_string($length) { mt_rand(); $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $randomString = ''; for ($i = 0; $i < $length; $i++) { $index = rand(0, strlen($characters) - 1); $randomString .= $characters[$index]; } return $randomString; } } if (!function_exists('create_account')) { function create_account() { do { $randomString = 'qn_' . random_string(16) . '_' . random_string(4); } while (User::where('account', $randomString)->find()); return $randomString; } } if (!function_exists('curl_file_exist')) { function curl_file_exist($url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_NOBODY, true); // 不需要返回体 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 返回结果而不是直接输出 curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpCode == 200; } }