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 @@