From deec0e9a876d03043fce38cae34530e1e48e7a8e Mon Sep 17 00:00:00 2001 From: mzl Date: Fri, 21 Mar 2025 15:09:49 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A3=9E=E4=B9=A6=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controller/FeishuController.php | 186 ++++++ app/service/FeishuService.php | 210 ++++++ composer.json | 4 +- composer.lock | 958 +++++++++++++++++++++++++++- config/cache.php | 31 + config/feishu.php | 20 + config/route.php | 7 +- start.php | 1 - 8 files changed, 1404 insertions(+), 13 deletions(-) create mode 100644 app/controller/FeishuController.php create mode 100644 app/service/FeishuService.php create mode 100644 config/cache.php create mode 100644 config/feishu.php diff --git a/app/controller/FeishuController.php b/app/controller/FeishuController.php new file mode 100644 index 0000000..3465cb0 --- /dev/null +++ b/app/controller/FeishuController.php @@ -0,0 +1,186 @@ +all(); + + // 获取凭证 + $certificate = config('feishu.mbaf'); + + // 飞书服务 + $class = new \app\service\FeishuService($certificate['appId'], $certificate['appSecret'], $certificate['state']); + + if (isset($param['code']) && $param['code']) { + + // 获取token + $userAccessToken = $class->userAccessToken($param['code'], $certificate['rUrl']); + + // 获取用户信息 + $rst = $class->userInfo($userAccessToken['access_token']); + if ($rst['code'] != 0) { + throw new BusinessException('授权失败,请重试'); + } + + // var_dump($rst); + // array(3) { + // ["code"]=> + // int(0) + // ["data"]=> + // array(11) { + // ["avatar_big"]=> + // string(168) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=640x640&cut_type=&quality=&format=image&sticker_format=.webp" + // ["avatar_middle"]=> + // string(168) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=240x240&cut_type=&quality=&format=image&sticker_format=.webp" + // ["avatar_thumb"]=> + // string(166) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=72x72&cut_type=&quality=&format=image&sticker_format=.webp" + // ["avatar_url"]=> + // string(166) "https://s1-imfile.feishucdn.com/static-resource/v1/v3_00ie_7cc82f38-0a89-43d4-8b2c-d90fc9d9176g~?image_size=72x72&cut_type=&quality=&format=image&sticker_format=.webp" + // ["en_name"]=> + // string(9) "李佳博" + // ["mobile"]=> + // string(14) "+8615738985690" + // ["name"]=> + // string(9) "李佳博" + // ["open_id"]=> + // string(35) "ou_37bb7cfc4311c858ea32461700fa1a43" + // ["tenant_key"]=> + // string(16) "14e7bc0fe5985740" + // ["union_id"]=> + // string(35) "on_a3fdbca48cd9477a140c7f2167a63691" + // ["user_id"]=> + // string(8) "481g947d" + // } + // ["msg"]=> + // string(7) "success" + // } + + return json($rst); + } else { + // 授权地址 + $rst = $class->authorize($certificate); + // 拉起授权 + return redirect($rst); + } + } + + + public function send() + { + // 获取凭证 + $certificate = config('feishu.mbaf'); + + // 飞书服务 + $class = new \app\service\FeishuService($certificate['appId'], $certificate['appSecret'], $certificate['state']); + + // $receiveId = 'ou_37bb7cfc4311c858ea32461700fa1a43'; + $receiveId = 'ou_a3b97543acbf1b28d978356bb08f85dd'; + + // 富文本 类型 + // $content = "{ + // \"zh_cn\":{ + // \"title\":\"演示-消息提醒\", + // \"content\":[ + // [{ + // \"tag\":\"text\", + // \"text\":\"示例内容 - demo\", + // \"style\":[\"bold\"] + // }], + // [{ + // \"tag\":\"hr\" + // }], + // [{ + // \"tag\":\"a\", + // \"href\":\"http://219.157.255.213:25321/feishu/show\", + // \"text\":\"查看详情\" + // }] + // ] + // } + // }"; + + // 卡片 类型 + $content = "{ + \"config\":{ + \"wide_screen_mode\":true + }, + \"elements\":[{ + \"tag\":\"div\", + \"text\":{ + \"content\":\"**测试内容**,测试内容,测试内容。\\n 测试内容,测试内容,测试内容。\\n\\n 📬 示例1 示例1 示例1 \\n 😍 示例1 示例1 示例1 \\n 📝 示例1 示例1 示例1 \\n 🙌 示例1 示例1 示例1 \", + \"tag\":\"lark_md\" + }},{ + \"actions\":[{ + \"tag\":\"button\", + \"text\":{ + \"content\":\"立即查看\", + \"tag\":\"plain_text\" + }, + \"type\":\"primary\", + \"url\":\"http://219.157.255.213:25321/feishu/show\" + }], + \"tag\":\"action\" + }], + \"header\":{ + \"template\":\"turquoise\", + \"title\":{ + \"content\":\"📚标题\", + \"tag\":\"plain_text\" + } + } + }"; + $msgType = 'interactive'; + $receiveIdtype = 'open_id'; + + $result = $class->sendMessages($receiveId, $content, $msgType, $receiveIdtype); + return json($result); + } + + public function show() + { + return '
查看详情 - 示例页面
'; + } +} + +// 凭证 +function certificate($gs = ''){ + $data = []; + switch ($gs) { + case "xinyouhe": + $data = [ + 'appId' => "cli_a73e1e6406fa501c", + 'appSecret' => "9cMfxujjGG9JPmNfNcOwUdCoIXqaM1wY", + 'rUrl' => "https://server.xyh.hnzhwlkj.club", + 'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot", + 'state' => "xinyouhe" + ]; + break; + + case "mbaf": + $data = [ + 'appId' => "cli_a75839fb4ff85028", + 'appSecret' => "VsqLvwsRzpmisBVbrTIuKdNCvRCO447d", + 'rUrl' => "https://server.xyh.hnzhwlkj.club", + 'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot", + 'state' => "mbaf" + ]; + break; + + default: + throw new BusinessException('未授权应用'); + break; + } + return $data; +} \ No newline at end of file diff --git a/app/service/FeishuService.php b/app/service/FeishuService.php new file mode 100644 index 0000000..e38e6a8 --- /dev/null +++ b/app/service/FeishuService.php @@ -0,0 +1,210 @@ +baseUri = 'https://open.larksuite.com/open-apis/'; + } else { + $this->baseUri = 'https://open.feishu.cn/open-apis/'; + } + + $this->appId = $appId; + $this->appSecret = $appSecret; + $this->gs = $gs; + + $this->client = new Client([ + 'base_uri' => $this->baseUri + ]); + + $this->options = [ + 'headers' => [ + 'Content-Type' => 'application/json; charset=utf-8' + ] + ]; + } + + /** + * 异常 + */ + public function error() + { + return $this->error; + } + + /** + * 请求 + */ + public function requestResult($url = "", $method = "POST") + { + try { + $res = $this->client->request($method, $this->baseUri.$url, $this->options); + if ($res->getBody()) { + $result = json_decode($res->getBody(), true); + // var_dump($result); + if ($result["code"] === 0) { + return $result; + } else { + $this->error = $result["msg"]; + return false; + } + } else { + $this->error = "result error"; + return false; + } + } catch (RequestException $e) { + if ($e->hasResponse()) { + var_dump('2 :'.$e->getResponse()->getBody()); + throw new BusinessException($e->getResponse()->getBody()); + } else { + var_dump('3 :'.$e->getMessage()); + throw new BusinessException($e->getMessage()); + } + } catch (\Throwable $th) { + var_dump('4 :'.$th->getFile()."|".$th->getLine()."|".$th->getMessage()); + $this->error = $th->getFile()."|".$th->getLine()."|".$th->getMessage(); + return false; + } + } + + /** + * 授权 + */ + public function authorize($certificate, $url = 'authen/v1/authorize') + { + $arr = [ + 'app_id' => $certificate['appId'], + 'redirect_uri' => $certificate['rUrl'], + 'scope' => $certificate['scope'], + 'state' => $certificate['state'] + ]; + $queryData = http_build_query($arr); + return $this->baseUri.$url.'?'.$queryData; + } + + /** + * 自建应用获取 tenant_access_token + */ + public function tenantAccessToken() + { + $tenantAccessToken = Cache::get($this->gs.'-tenantAccessToken'); + if (!$tenantAccessToken) { + $this->options["json"] = [ + "app_id" => $this->appId, + "app_secret" => $this->appSecret + ]; + $rst = $this->requestResult('auth/v3/tenant_access_token/internal', 'POST'); + // var_dump($rst); + if ($rst) { + $tenantAccessToken = $rst['tenant_access_token']; + Cache::set($this->gs.'-tenantAccessToken', $tenantAccessToken, $rst['expire']); + } else { + throw new BusinessException('tenant_access_token 获取失败'); + } + } + return $tenantAccessToken; + } + + /** + * 通过手机号或邮箱获取用户 ID + */ + public function getUserIdByPhoneOrEmail($phone = '', $userIdType = 'open_id') + { + $this->options["headers"] = [ + "Authorization" => "Bearer " . $this->tenantAccessToken(), + "Content-Type" => "application/json; charset=utf-8" + ]; + $this->options["json"] = [ + "emails" => [], + "mobiles" => [$phone], + "include_resigned" => false + ]; + $rst = $this->requestResult('contact/v3/users/batch_get_id?user_id_type='.$userIdType, 'POST'); + return $rst; + } + + /** + * 发送消息 + */ + public function sendMessages($receiveId = '', $content = '', $msgType = 'text', $receiveIdtype = 'open_id') + { + $this->options["headers"] = [ + "Authorization" => "Bearer " . $this->tenantAccessToken(), + "Content-Type" => "application/json; charset=utf-8" + ]; + $this->options["json"] = [ + "receive_id" => $receiveId, + "msg_type" => $msgType, + "content" => $content + ]; + $rst = $this->requestResult('im/v1/messages?receive_id_type='.$receiveIdtype, 'POST'); + return $rst; + } + + /** + * 编辑消息 + */ + public function updateSendMessages($messageId = '', $content = '', $msgType = 'text') + { + $this->options["headers"] = [ + "Authorization" => "Bearer " . $this->tenantAccessToken(), + "Content-Type" => "application/json; charset=utf-8" + ]; + $this->options["json"] = [ + "msg_type" => $msgType, + "content" => $content + ]; + $rst = $this->requestResult('im/v1/messages/'.$messageId, 'PUT'); + return $rst; + } + + /** + * 用户 user_access_token + */ + public function userAccessToken($code = "", $redirect_uri = "") + { + $this->options["headers"] = [ + "Content-Type" => "application/json; charset=utf-8" + ]; + $this->options["json"] = [ + "grant_type" => "authorization_code", + "client_id" => $this->appId, + "client_secret" => $this->appSecret, + "code" => $code, + "redirect_uri" => $redirect_uri + ]; + return $this->requestResult('authen/v2/oauth/token'); + } + + /** + * 用户信息 + */ + public function userInfo($userAccessToken = "") + { + $this->options["headers"] = [ + "Authorization" => "Bearer " . $userAccessToken, + "Content-Type" => "application/json; charset=utf-8" + ]; + return $this->requestResult('authen/v1/user_info', "GET"); + } +} \ No newline at end of file diff --git a/composer.json b/composer.json index 4bc81aa..6ad16e2 100644 --- a/composer.json +++ b/composer.json @@ -38,7 +38,9 @@ "phpmailer/phpmailer": "^6.9", "shopwwi/webman-filesystem": "^2.0", "iidestiny/flysystem-oss": "4", - "vlucas/phpdotenv": "^5.6" + "vlucas/phpdotenv": "^5.6", + "guzzlehttp/guzzle": "^7.9", + "webman/cache": "^2.1" }, "suggest": { "ext-event": "For better performance. " diff --git a/composer.lock b/composer.lock index 4d9eb3d..4eb2e34 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8d5fe425388a62621d55a80ee07c34e8", + "content-hash": "ab7f80fdfdb27cc3009ad39dfc7f315f", "packages": [ { "name": "aliyuncs/oss-sdk-php", @@ -409,6 +409,331 @@ ], "time": "2025-02-09T22:43:44+00:00" }, + { + "name": "guzzlehttp/guzzle", + "version": "7.9.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b", + "reference": "d281ed313b989f213357e3be1a179f02196ac99b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.9.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2024-07-24T11:22:20+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2024-10-17T10:06:22+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "reference": "a70f5c95fb43bc83f07c9c948baa0dc1829bf201", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.7.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2024-07-18T11:15:46+00:00" + }, { "name": "iidestiny/flysystem-oss", "version": "4.0", @@ -1811,6 +2136,55 @@ ], "time": "2024-07-20T21:41:07+00:00" }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" + }, { "name": "psr/clock", "version": "1.0.0", @@ -1912,6 +2286,166 @@ }, "time": "2021-11-05T16:47:00+00:00" }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, { "name": "psr/log", "version": "3.0.2", @@ -2013,6 +2547,50 @@ }, "time": "2021-10-29T13:26:27+00:00" }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, { "name": "shopwwi/webman-filesystem", "version": "v2.0.0", @@ -2072,6 +2650,180 @@ }, "time": "2025-03-17T11:14:43+00:00" }, + { + "name": "symfony/cache", + "version": "v7.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache.git", + "reference": "d33cd9e14326e14a4145c21e600602eaf17cc9e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache/zipball/d33cd9e14326e14a4145c21e600602eaf17cc9e7", + "reference": "d33cd9e14326e14a4145c21e600602eaf17cc9e7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/cache": "^2.0|^3.0", + "psr/log": "^1.1|^2|^3", + "symfony/cache-contracts": "^2.5|^3", + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/var-exporter": "^6.4|^7.0" + }, + "conflict": { + "doctrine/dbal": "<3.6", + "symfony/dependency-injection": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/var-dumper": "<6.4" + }, + "provide": { + "psr/cache-implementation": "2.0|3.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0", + "symfony/cache-implementation": "1.1|2.0|3.0" + }, + "require-dev": { + "cache/integration-tests": "dev-master", + "doctrine/dbal": "^3.6|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Cache\\": "" + }, + "classmap": [ + "Traits/ValueWrapper.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", + "homepage": "https://symfony.com", + "keywords": [ + "caching", + "psr6" + ], + "support": { + "source": "https://github.com/symfony/cache/tree/v7.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-02-26T09:57:54+00:00" + }, + { + "name": "symfony/cache-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/cache-contracts.git", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "reference": "15a4f8e5cd3bce9aeafc882b1acab39ec8de2c1b", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/cache": "^3.0" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Cache\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to caching", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, { "name": "symfony/clock", "version": "v7.2.0", @@ -2390,13 +3142,7 @@ "type": "zip", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "shasum": "", - "mirrors": [ - { - "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%", - "preferred": true - } - ] + "shasum": "" }, "require": { "php": ">=7.2" @@ -2540,6 +3286,89 @@ ], "time": "2024-09-09T11:45:10+00:00" }, + { + "name": "symfony/service-contracts", + "version": "v3.5.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.5-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:20:29+00:00" + }, { "name": "symfony/translation", "version": "v7.2.4", @@ -2796,6 +3625,82 @@ ], "time": "2025-01-17T11:39:41+00:00" }, + { + "name": "symfony/var-exporter", + "version": "v7.2.4", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "4ede73aa7a73d81506002d2caadbbdad1ef5b69a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/4ede73aa7a73d81506002d2caadbbdad1ef5b69a", + "reference": "4ede73aa7a73d81506002d2caadbbdad1ef5b69a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.2.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-02-13T10:27:23+00:00" + }, { "name": "vlucas/phpdotenv", "version": "v5.6.1", @@ -2960,6 +3865,43 @@ ], "time": "2024-11-21T01:49:47+00:00" }, + { + "name": "webman/cache", + "version": "v2.1.1", + "source": { + "type": "git", + "url": "https://github.com/webman-php/cache.git", + "reference": "e420cb82a1db048dd6a02944c83ca5c628785883" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webman-php/cache/zipball/e420cb82a1db048dd6a02944c83ca5c628785883", + "reference": "e420cb82a1db048dd6a02944c83ca5c628785883", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/simple-cache": "^3.0", + "symfony/cache": "^6.0 || ^7.0", + "workerman/webman-framework": "^2.1 || dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "support\\": "src/support", + "Webman\\Cache\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "support": { + "issues": "https://github.com/webman-php/cache/issues", + "source": "https://github.com/webman-php/cache/tree/v2.1.1" + }, + "time": "2025-03-10T06:11:35+00:00" + }, { "name": "webman/database", "version": "v2.1.5", diff --git a/config/cache.php b/config/cache.php new file mode 100644 index 0000000..74775dc --- /dev/null +++ b/config/cache.php @@ -0,0 +1,31 @@ + + * @copyright walkor + * @link http://www.workerman.net/ + * @license http://www.opensource.org/licenses/mit-license.php MIT License + */ + +return [ + 'default' => 'file', + 'stores' => [ + 'file' => [ + 'driver' => 'file', + 'path' => runtime_path('cache') + ], + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default' + ], + 'array' => [ + 'driver' => 'array' + ] + ] +]; \ No newline at end of file diff --git a/config/feishu.php b/config/feishu.php new file mode 100644 index 0000000..4b30c07 --- /dev/null +++ b/config/feishu.php @@ -0,0 +1,20 @@ + [ + 'appId' => "cli_a73e1e6406fa501c", + 'appSecret' => "9cMfxujjGG9JPmNfNcOwUdCoIXqaM1wY", + 'rUrl' => "http://219.157.255.213:25321/feishu/auth", + 'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot", + 'state' => "xinyouhe", + 'baseUri' => "https://open.feishu.cn/open-apis/" + ], + 'mbaf' => [ + 'appId' => "cli_a75839fb4ff85028", + 'appSecret' => "VsqLvwsRzpmisBVbrTIuKdNCvRCO447d", + 'rUrl' => "http://219.157.255.213:25321/feishu/auth", + 'scope' => "contact:user.base:readonly contact:contact.base:readonly contact:user.employee_id:readonly im:message:send_as_bot", + 'state' => "mbaf", + 'baseUri' => "https://open.larksuite.com/open-apis/" + ] +]; \ No newline at end of file diff --git a/config/route.php b/config/route.php index 6851ca6..eb64dbd 100644 --- a/config/route.php +++ b/config/route.php @@ -28,6 +28,7 @@ Route::post('/upload', [app\controller\UploadController::class, 'uploadImage']); - - - +// 飞书 +Route::post('/feishu/auth', [app\controller\FeishuController::class, 'auth']); +Route::post('/feishu/show', [app\controller\FeishuController::class, 'show']); +Route::post('/feishu/send', [app\controller\FeishuController::class, 'send']); \ No newline at end of file diff --git a/start.php b/start.php index 2399638..41ad7ef 100644 --- a/start.php +++ b/start.php @@ -2,5 +2,4 @@