|
@@ -0,0 +1,322 @@
|
|
|
|
|
+<?php
|
|
|
|
|
+namespace App\Tools;
|
|
|
|
|
+use Hyperf\Snowflake\IdGeneratorInterface;
|
|
|
|
|
+use Hyperf\Context\ApplicationContext;
|
|
|
|
|
+use function Hyperf\Support\env;
|
|
|
|
|
+
|
|
|
|
|
+class PublicData
|
|
|
|
|
+{
|
|
|
|
|
+ /**
|
|
|
|
|
+ * ceshi-todo
|
|
|
|
|
+ * 递归查询
|
|
|
|
|
+ * @param $menuItems
|
|
|
|
|
+ * @param $parentId
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function buildMenuTree($menuItems, $parentId = 0) {
|
|
|
|
|
+ $tree = [];
|
|
|
|
|
+ foreach ($menuItems as $item) {
|
|
|
|
|
+ if ($item['pid'] == $parentId) {
|
|
|
|
|
+ // 找到子菜单
|
|
|
|
|
+ $children = self::buildMenuTree($menuItems, $item['id']);
|
|
|
|
|
+ // 如果子菜单存在,则添加到当前菜单的children中
|
|
|
|
|
+ if ($children) {
|
|
|
|
|
+ $item['children'] = $children;
|
|
|
|
|
+ }else{
|
|
|
|
|
+ $item['children'] = [];
|
|
|
|
|
+ }
|
|
|
|
|
+ // 将当前菜单添加到树中
|
|
|
|
|
+ $tree[] = $item;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $tree;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static function buildCategoryTree($menuItems, $parentId = 0) {
|
|
|
|
|
+ $tree = [];
|
|
|
|
|
+ foreach ($menuItems as $item) {
|
|
|
|
|
+ if ($item['pid'] == $parentId) {
|
|
|
|
|
+ // 找到子菜单
|
|
|
|
|
+ $children = self::buildCategoryTree($menuItems, $item['category_id']);
|
|
|
|
|
+ // 如果子菜单存在,则添加到当前菜单的children中
|
|
|
|
|
+ if ($children) {
|
|
|
|
|
+ $item['children'] = $children;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 将当前菜单添加到树中
|
|
|
|
|
+ $tree[] = $item;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $tree;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 把数组里面的某一个字段作为key
|
|
|
|
|
+ * @param $array
|
|
|
|
|
+ * @param $column
|
|
|
|
|
+ * @return array
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function arrayColumnAsKey($array, $column) {
|
|
|
|
|
+ $result = [];
|
|
|
|
|
+ foreach ($array as $item) {
|
|
|
|
|
+ if (isset($item[$column])) {
|
|
|
|
|
+ $result[$item[$column]] = $item;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果字段不存在,你可以选择跳过、使用默认值或抛出异常
|
|
|
|
|
+ // 这里我们选择跳过
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return $result;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 计算两个时间差的天数
|
|
|
|
|
+ * @param $sTime
|
|
|
|
|
+ * @param $eTime
|
|
|
|
|
+ * @return float
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function residueDay($sTime,$eTime)
|
|
|
|
|
+ {
|
|
|
|
|
+ $startTime = strtotime($sTime);
|
|
|
|
|
+ $endTime = strtotime($eTime);
|
|
|
|
|
+ $diffDays = floor(($endTime - $startTime) / (60 * 60 * 24));
|
|
|
|
|
+ return $diffDays;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static function uuid()
|
|
|
|
|
+ {
|
|
|
|
|
+ $container = ApplicationContext::getContainer();
|
|
|
|
|
+ $generator = $container->get(IdGeneratorInterface::class);
|
|
|
|
|
+
|
|
|
|
|
+ return $generator->generate();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static function http_get($url)
|
|
|
|
|
+ {
|
|
|
|
|
+ $oCurl = curl_init();
|
|
|
|
|
+ if (stripos($url, "https://") !== false) {
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
|
|
|
|
+ }
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_URL, $url);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
|
+ $sContent = curl_exec($oCurl);
|
|
|
|
|
+ $aStatus = curl_getinfo($oCurl);
|
|
|
|
|
+ curl_close($oCurl);
|
|
|
|
|
+ if (intval($aStatus["http_code"]) == 200) {
|
|
|
|
|
+ return $sContent;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * POST 请求
|
|
|
|
|
+ * @param string $url
|
|
|
|
|
+ * @param array $param
|
|
|
|
|
+ * @param boolean $post_file 是否文件上传
|
|
|
|
|
+ * @return string content
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function http_post($url, $param, $post_file = false)
|
|
|
|
|
+ {
|
|
|
|
|
+ $oCurl = curl_init();
|
|
|
|
|
+ if (stripos($url, "https://") !== false) {
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
|
|
|
|
|
+ }
|
|
|
|
|
+ if (is_string($param) || $post_file) {
|
|
|
|
|
+ $strPOST = $param;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ $aPOST = [];
|
|
|
|
|
+ foreach ($param as $key => $val) {
|
|
|
|
|
+ $aPOST[] = $key . "=" . urlencode($val);
|
|
|
|
|
+ }
|
|
|
|
|
+ $strPOST = join("&", $aPOST);
|
|
|
|
|
+ }
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_URL, $url);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_POST, true);
|
|
|
|
|
+ curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
|
|
|
|
|
+ $sContent = curl_exec($oCurl);
|
|
|
|
|
+ $aStatus = curl_getinfo($oCurl);
|
|
|
|
|
+ curl_close($oCurl);
|
|
|
|
|
+ if (intval($aStatus["http_code"]) == 200) {
|
|
|
|
|
+ return $sContent;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * POST 请求
|
|
|
|
|
+ * @param string $url
|
|
|
|
|
+ * @param array $param
|
|
|
|
|
+ * @param boolean $post_file 是否文件上传
|
|
|
|
|
+ * @return string content
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function http_post_zp($url, $data, $options = [])
|
|
|
|
|
+ {
|
|
|
|
|
+ // 初始化CURL会话
|
|
|
|
|
+ $ch = curl_init($url);
|
|
|
|
|
+ var_dump("参数:",$data);
|
|
|
|
|
+ // 设置CURL选项
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_HEADER, false); // 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_POST, true); // 发送一个常规的POST请求。
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); // 要传递的POST数据,这里使用http_build_query将数组转换为URL编码的查询字符串。
|
|
|
|
|
+ $headers = [
|
|
|
|
|
+ 'Authorization: Bearer be1856920c54ac537b530d69bc2eda73.gOO2BMq9NXavzEMq',
|
|
|
|
|
+ 'Content-Type: application/json',
|
|
|
|
|
+// 'Custom-Header: customHeaderValue'
|
|
|
|
|
+ ];
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
|
|
+ // 如果有额外的CURL选项,则合并它们
|
|
|
|
|
+ if (!empty($options)) {
|
|
|
|
|
+ curl_setopt_array($ch, $options);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 执行CURL会话并获取响应
|
|
|
|
|
+ $response = curl_exec($ch);
|
|
|
|
|
+ // 检查是否有CURL错误
|
|
|
|
|
+ if (curl_errno($ch)) {
|
|
|
|
|
+ $error_msg = curl_error($ch);
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+ throw new Exception("CURL Error: $error_msg");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 获取HTTP状态码
|
|
|
|
|
+ $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
|
+
|
|
|
|
|
+ // 关闭CURL会话
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+
|
|
|
|
|
+ // 返回一个包含响应和HTTP状态码的数组
|
|
|
|
|
+ $responseBody = $response;
|
|
|
|
|
+ $headerEnd = strpos($response, "\r\n\r\n");
|
|
|
|
|
+
|
|
|
|
|
+ if ($headerEnd !== false) {
|
|
|
|
|
+ // 去除响应头,只保留响应体
|
|
|
|
|
+ $responseBody = substr($response, $headerEnd + 4); // +4 是因为 "\r\n\r\n" 有4个字符
|
|
|
|
|
+// echo $responseBody; // 输出:This is the response body.
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果没有找到空行,可能响应格式不正确或没有响应头
|
|
|
|
|
+// echo "No headers found in response.";
|
|
|
|
|
+ }
|
|
|
|
|
+ return [
|
|
|
|
|
+ 'response' => $responseBody,
|
|
|
|
|
+ 'http_code' => $http_code
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 历史上的今天
|
|
|
|
|
+ * @return mixed
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function getHistoryToday()
|
|
|
|
|
+ {
|
|
|
|
|
+ $api_url = "https://api.52vmy.cn/api/wl/today?type=json";
|
|
|
|
|
+ $ch = curl_init();
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $api_url);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
|
+ $response = curl_exec($ch);
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+ $data = json_decode($response, true);
|
|
|
|
|
+ return $data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取谜语
|
|
|
|
|
+ * @return mixed
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function addRiddle()
|
|
|
|
|
+ {
|
|
|
|
|
+ $api_url = "https://v.api.aa1.cn/api/api-miyu/index.php";
|
|
|
|
|
+ $ch = curl_init();
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $api_url);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
|
+ $response = curl_exec($ch);
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+ var_dump("返回数据:",$response);
|
|
|
|
|
+ $cleanStr = preg_replace('/<script[^>]*?>.*?<\/script>/is', '', $response);
|
|
|
|
|
+ $jsonStr = trim(preg_replace('/\s+/', ' ', $cleanStr)); // 压缩空白符
|
|
|
|
|
+ $jsonStr = preg_replace('/^.*?({.*})$/', '$1', $jsonStr); // 提取最后一个完整 JSON
|
|
|
|
|
+ $arr = json_decode($jsonStr, true);
|
|
|
|
|
+ if (json_last_error() !== JSON_ERROR_NONE) {
|
|
|
|
|
+ return json_last_error_msg();
|
|
|
|
|
+ }
|
|
|
|
|
+ var_dump("返回数据111:",$response);
|
|
|
|
|
+ return $arr;
|
|
|
|
|
+ }
|
|
|
|
|
+ /**
|
|
|
|
|
+ * @param $text
|
|
|
|
|
+ * @return bool|string
|
|
|
|
|
+ */
|
|
|
|
|
+ public static function getCouplet($text="") {
|
|
|
|
|
+ if($text){
|
|
|
|
|
+ $api_url = "https://apis.tianapi.com/msdl/index?key=44c4f9b3d66ce06900a098c78b90478f&num=10&fenlei=".urlencode($text);
|
|
|
|
|
+ }else{
|
|
|
|
|
+ $api_url = "https://apis.tianapi.com/msdl/index?key=44c4f9b3d66ce06900a098c78b90478f&num=10";
|
|
|
|
|
+ }
|
|
|
|
|
+ var_dump("请求地址:",$api_url);
|
|
|
|
|
+ $ch = curl_init();
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_URL, $api_url);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
|
+ $response = curl_exec($ch);
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+ $data = json_decode($response, true);
|
|
|
|
|
+ return $data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static function im_post($url, $data, $options = [])
|
|
|
|
|
+ {
|
|
|
|
|
+ // 初始化CURL会话
|
|
|
|
|
+ $ch = curl_init($url);
|
|
|
|
|
+ // JSON 编码(保持中文不转义)
|
|
|
|
|
+ $jsonBody = is_string($data) ? $data : json_encode($data, JSON_UNESCAPED_UNICODE);
|
|
|
|
|
+ // 基础选项
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_HEADER, false);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_POST, true);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonBody);
|
|
|
|
|
+ // HTTPS 兼容
|
|
|
|
|
+ if (stripos($url, 'https://') === 0) {
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
|
|
|
|
+ }
|
|
|
|
|
+ // Header:Content-Type JSON,Authorization(优先使用传入的)
|
|
|
|
|
+ $authorization = $options['authorization'] ?? 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI';
|
|
|
|
|
+ $headers = [
|
|
|
|
|
+ 'Content-Type: application/json',
|
|
|
|
|
+ 'Accept: application/json',
|
|
|
|
|
+ 'Authorization: ' . $authorization,
|
|
|
|
|
+ ];
|
|
|
|
|
+ // 允许外部追加自定义 header(数组,形如 ['X-xxx: yyy'])
|
|
|
|
|
+ if (!empty($options['headers']) && is_array($options['headers'])) {
|
|
|
|
|
+ $headers = array_merge($headers, $options['headers']);
|
|
|
|
|
+ }
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
|
|
|
|
+ // 超时设置(可通过 options 覆盖)
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, (int)($options['connect_timeout'] ?? 5));
|
|
|
|
|
+ curl_setopt($ch, CURLOPT_TIMEOUT, (int)($options['timeout'] ?? 15));
|
|
|
|
|
+ // 追加额外的 CURL 选项(如需)
|
|
|
|
|
+ if (!empty($options['curl']) && is_array($options['curl'])) {
|
|
|
|
|
+ curl_setopt_array($ch, $options['curl']);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 执行请求
|
|
|
|
|
+ $response = curl_exec($ch);
|
|
|
|
|
+ if ($response === false) {
|
|
|
|
|
+ $errorMsg = curl_error($ch);
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+ throw new \Exception('CURL Error: ' . $errorMsg);
|
|
|
|
|
+ }
|
|
|
|
|
+ // 获取HTTP状态码
|
|
|
|
|
+ $httpCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
|
|
|
+ // 关闭会话
|
|
|
|
|
+ curl_close($ch);
|
|
|
|
|
+ // 返回结果
|
|
|
|
|
+ return json_decode($response,true);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+}
|