飞书API
extend目录下,API
<?php
// +----------------------------------------------------------------------
// | 飞书API
// +----------------------------------------------------------------------
// | COPYRIGHT (C) 2021 http://www.jeoshi.com All rights reserved.
// +----------------------------------------------------------------------
// | AUTHOR : 陈龙
// | DATE : 2024/01/19 10:45:47
// | VERSION:1.0.0
// +----------------------------------------------------------------------
namespace feishu;class Api extends Request
{public static $instance = null;/*** 构造函数*/public function __construct($option = []){parent::__construct();$this->setAppConfig($option['company_id'] ?? 0);}/*** @desc 单例* @return static|null* @author 陈龙* @date 2024-01-09 11:00*/public static function instance(){if (is_null(self::$instance)) {self::$instance = new static;}return self::$instance;}/*** @desc 自建应用获取 tenant_access_token* https://open.feishu.cn/document/server-docs/authentication-management/access-token/tenant_access_token_internal* @param $up_cache 刷新缓存* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function getTenantToken($up_cache = false){return $this->getTenantAccessToken($up_cache);}/*** @desc 创建用户* https://open.feishu.cn/document/server-docs/contact-v3/user/create* @param $data 请求参数* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function createUser($data = []){return $this->_createUser($data);}/*** @desc 修改用户部分信息* https://open.feishu.cn/document/server-docs/contact-v3/user/patch* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function updateUserInfo($path = [], $params = [], $data = []){return $this->_updateUserInfo($path, $params, $data);}/*** @desc 删除用户* https://open.feishu.cn/document/server-docs/contact-v3/user/delete* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function deleteUser($path = [], $params = [], $data = []){return $this->_deleteUser($path, $params, $data);}/*** @desc 恢复已删除用户* https://open.feishu.cn/document/server-docs/contact-v3/user/resurrect* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function resurrectUser($path = [], $params = [], $data = []){return $this->_resurrectUser($path, $params, $data);}/*** @desc 获取单个用户信息* https://open.feishu.cn/document/server-docs/contact-v3/user/get* @param $path 路径参数* @param $params 查询参数* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function getUser($path = [], $params = []){if (empty($params)) $params = ['user_id_type' => 'user_id'];return $this->_getUser($path, $params);}/*** @desc 批量获取用户信息* https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/contact-v3/user/batch* @param $params 查询参数* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function batchGetUser($params = []){return $this->_batchGetUser($params);}/*** @desc 获取部门直属用户列表* https://open.feishu.cn/document/server-docs/contact-v3/user/find_by_department* @param $params 查询参数* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function findUserByDepartment($params = []){return $this->_findUserByDepartment($params);}/*** @desc 通过手机号或邮箱获取用户 ID* https://open.feishu.cn/document/server-docs/contact-v3/user/batch_get_id* @param $params 查询参数* @param $data 请求参数* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function batchGetId($params = [], $data = []){if (empty($params)) $params = ['user_id_type' => 'user_id'];return $this->_batchGetId($params, $data);}/*** @desc 更新用户ID* https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/contact-v3/user/update_user_id* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function updateUserId($path = [], $params = [], $data = []){return $this->_updateUserId($path, $params, $data);}/*** @desc 创建部门* https://open.feishu.cn/document/server-docs/contact-v3/department/create* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 19:49*/public function createDepartment($data = []){return $this->_createDepartment($data);}/*** @desc 删除部门* https://open.feishu.cn/document/server-docs/contact-v3/department/delete* @param $path 路径参数* @param $params 查询参数* @return array|mixed* @author 陈龙* @date 2024-01-09 19:55*/public function deleteDepartment($path = [], $params = []){return $this->_deleteDepartment($path, $params);}/*** @desc 修改部门部分信息* https://open.feishu.cn/document/server-docs/contact-v3/department/patch* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function updateDepartmentInfo($path = [], $params = [], $data = []){return $this->_updateDepartmentInfo($path, $params, $data);}/*** @desc 更新部门所有信息* https://open.feishu.cn/document/server-docs/contact-v3/department/update* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function updateDepartmentAllInfo($path = [], $params = [], $data = []){return $this->_updateDepartmentAllInfo($path, $params, $data);}/*** @desc 获取单个部门信息* https://open.feishu.cn/document/server-docs/contact-v3/department/get* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function getDepartment($path = [], $params = []){return $this->_getDepartment($path, $params);}/*** @desc 批量获取部门信息* https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/contact-v3/department/batch* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function batchGetDepartment($params = []){return $this->_batchGetDepartment($params);}/*** @desc 获取子部门列表* https://open.feishu.cn/document/server-docs/contact-v3/department/children* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function getDepartmentChildren($path = [], $params = []){return $this->_getDepartmentChildren($path, $params);}/*** @desc 获取父部门信息* https://open.feishu.cn/document/server-docs/contact-v3/department/parent* @return mixed* @author 陈龙* @date 2024-01-09 11:02*/public function getDepartmentParent($params = []){return $this->_getDepartmentParent($params);}/*** @desc 更新部门ID* https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/reference/contact-v3/department/update_department_id* @param $path 路径参数* @param $params 查询参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function updateDepartmentId($path = [], $params = [], $data = []){return $this->_updateDepartmentId($path, $params, $data);}/*** @desc 创建角色* https://open.feishu.cn/document/server-docs/contact-v3/functional_role/create* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 19:50*/public function createRole($data = []){return $this->_createRole($data);}/*** @desc 修改角色名称* https://open.feishu.cn/document/server-docs/contact-v3/functional_role/update* @param $path 路径参数* @param $data 请求参数* @return array|mixed* @author 陈龙* @date 2024-01-09 19:55*/public function updateRoleName($path = [], $data = []){return $this->_updateRoleName($path, $data);}/*** @desc 删除角色* https://open.feishu.cn/document/server-docs/contact-v3/functional_role/delete* @param $path 路径参数* @return array|mixed* @author 陈龙* @date 2024-01-09 19:55*/public function deleteRole($path = []){return $this->_deleteRole($path);}/*** @desc 发送消息* https://open.feishu.cn/document/server-docs/im-v1/message/create* @param $data* @return array|mixed* @author 陈龙* @date 2024-08-14 13:57*/public function messages($data){if (empty($params)) $params = ['receive_id_type' => 'user_id'];return $this->_messages($params, $data);}
}
REQUEST:
<?php
// +----------------------------------------------------------------------
// | 飞书请求
// +----------------------------------------------------------------------
// | COPYRIGHT (C) 2021 http://www.jeoshi.com All rights reserved.
// +----------------------------------------------------------------------
// | AUTHOR : 陈龙
// | DATE : 2024/01/19 10:45:47
// | VERSION:1.0.0
// +----------------------------------------------------------------------
namespace feishu;use think\Cache;
use think\Config;class Request
{/*** @desc redis 对象* @var object*/private $redis;/*** 未经过封装的redis*/private $raw_redis;/*** 请求域名*/private $domain = "https://open.feishu.cn/open-apis";/*** 应用唯一标识*/private $app_id = '';/*** 应用秘钥*/private $app_secret = '';/*** 公司ID*/private $company_id = '';/*** 构造函数*/public function __construct(){$this->redis = Cache::connect(Config::get('cache.redis'));$this->raw_redis = $this->redis->handler();}/*** @desc setAppConfig* @return void* @author 陈龙* @date 2024-04-20 9:57*/public function setAppConfig($company_id){$this->company_id = $company_id;if ($company_id == 23){$this->app_id = Config::get('feishu.app')[23]['app_id'] ?? '';$this->app_secret = Config::get('feishu.app')[23]['app_secret'] ?? '';}elseif ($company_id == 36){$this->app_id = Config::get('feishu.app')[36]['app_id'] ?? '';$this->app_secret = Config::get('feishu.app')[36]['app_secret'] ?? '';}else{$this->app_id = Config::get('feishu.app')[0]['app_id'] ?? '';$this->app_secret = Config::get('feishu.app')[0]['app_secret'] ?? '';}}/*** @desc Curl请求* @param $url* @param $data* @param $method* @param $withToken* @param $header* @return bool|string* @author 陈龙* @date 2024-01-09 17:32*/public function httpCurl($url, $data, $method = 'POST', $withToken = true, $header = ''){$headers = $this->buildHeader($header,$withToken);$curl = curl_init(); // 启动一个CURL会话curl_setopt($curl, CURLOPT_URL, $url);curl_setopt($curl, CURLOPT_HEADER, 0);curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);$method = strtoupper($method);switch ($method){case 'POST':curl_setopt($curl, CURLOPT_POST, 1);curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));break;case 'PUT':case 'PATCH':case 'DELETE':curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));break;}$res = curl_exec($curl);curl_close($curl); //关闭URL请求return $res;}/*** @desc 构建头部参数* @param $header* @param $withToken* @return array* @author 陈龙* @date 2024-01-09 11:28*/public function buildHeader($header = '',$withToken = true){$headers[] = "Content-Type: application/json; charset=utf-8";if ($withToken) $headers[] = "Authorization: Bearer " . $this->getTenantAccessToken();if (!empty($header)) $headers[] = $header;return $headers;}/*** @desc 返回数据* @param $code 错误码,非 0 表示失败* @param $msg 错误描述* @param $data* @return array* @author 陈龙* @date 2024-01-09 18:13*/public function back($code = 0, $msg = '', $data = []){return ['code' => $code, 'msg' => $msg, 'data' => $data];}/*** @desc 错误返回* @param $msg* @param $code* @return array* @author 陈龙* @date 2024-01-09 18:34*/public function error($msg = '', $code = 400){return $this->back($code,$msg);}/*** @desc 自建应用获取 tenant_access_token* @param $up_cache* @return mixed|string* @author 陈龙* @date 2024-01-09 11:51*/public function getTenantAccessToken($up_cache = false){$redisKey = 'ehr:feishu:tenant_access_token:' . $this->company_id;$tenant_access_token = $this->redis->get($redisKey);if (empty($tenant_access_token) || $up_cache == true) {$url = $this->domain.'/auth/v3/tenant_access_token/internal';$data = ['app_id' => $this->app_id,'app_secret' => $this->app_secret,];$res = $this->httpCurl($url,$data,'POST',false);$res = json_decode($res,true);$tenant_access_token = $res['tenant_access_token'] ?? '';$expire = max(($res['expire'] ?? 0) - 900, 0);$this->redis->set($redisKey, $tenant_access_token, $expire);}return $tenant_access_token;}/*** @desc 创建用户* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:21*/public function _createUser($data = []){if (empty($data['name'] ?? '')) return $this->error('用户名不能为空');if (empty($data['mobile'] ?? '')) return $this->error('手机号不能为空');if (empty($data['department_ids'] ?? '')) return $this->error('用户所属部门不能为空');if (empty($data['employee_type'] ?? '')) return $this->error('员工类型不能为空');$url = $this->domain.'/contact/v3/users';$res = $this->httpCurl($url, $data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 修改用户部分信息* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _updateUserInfo($path = [], $params = [], $data = []){$user_id = $path['user_id'] ?? '';if (empty($user_id)) return $this->error('用户ID不能为空');$url = $this->domain."/contact/v3/users/{$user_id}?".http_build_query($params);$res = $this->httpCurl($url,$data,'PATCH');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 删除用户* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _deleteUser($path = [], $params = [], $data = []){$user_id = $path['user_id'] ?? '';if (empty($user_id)) return $this->error('用户ID不能为空');$url = $this->domain."/contact/v3/users/{$user_id}?".http_build_query($params);$res = $this->httpCurl($url,$data,'DELETE');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 恢复已删除用户* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _resurrectUser($path = [], $params = [], $data = []){$user_id = $path['user_id'] ?? '';if (empty($user_id)) return $this->error('用户ID不能为空');$url = $this->domain."/contact/v3/users/{$user_id}/resurrect?".http_build_query($params);$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 获取单个用户信息* @param $path* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _getUser($path = [], $params = []){$user_id = $path['user_id'] ?? '';if (empty($user_id)) return $this->error('用户ID不能为空');$url = $this->domain."/contact/v3/users/{$user_id}?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 批量获取用户信息* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _batchGetUser($params = []){$user_ids = $params['user_ids'] ?? '';if (empty($user_ids)) return $this->error('用户ID不能为空');$url = $this->domain."/contact/v3/users/batch?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 获取部门直属用户列表* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _findUserByDepartment($params = []){$url = $this->domain."/contact/v3/users/find_by_department?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 通过手机号或邮箱获取用户 ID* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _batchGetId($params = [],$data = []){$url = $this->domain."/contact/v3/users/batch_get_id?".http_build_query($params);$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 更新用户ID* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _updateUserId($path = [], $params = [], $data = []){$user_id = $path['user_id'] ?? '';if (empty($user_id)) return $this->error('用户ID不能为空');$new_user_id = $data['new_user_id'] ?? '';if (empty($new_user_id)) return $this->error('新用户ID不能为空');$url = $this->domain."/contact/v3/users/{$user_id}/update_user_id?".http_build_query($params);$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 创建部门* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 19:48*/public function _createDepartment($data = []){if (empty($data['name'] ?? '')) return $this->error('部门名称不能为空');$url = $this->domain.'/contact/v3/departments';$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 删除部门* @param $path* @return array|mixed* @author 陈龙* @date 2024-01-09 19:54*/public function _deleteDepartment($path = [], $params = []){$department_id = $path['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}?".http_build_query($params);$res = $this->httpCurl($url,'','DELETE');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 修改部门部分信息* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _updateDepartmentInfo($path = [], $params = [], $data = []){$department_id = $path['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}?".http_build_query($params);$res = $this->httpCurl($url,$data,'PATCH');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 更新部门所有信息* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _updateDepartmentAllInfo($path = [], $params = [], $data = []){$department_id = $path['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$name = $path['name'] ?? '';if (empty($name)) return $this->error('部门名称不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}?".http_build_query($params);$res = $this->httpCurl($url,$data,'PUT');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 获取单个部门信息* @param $path* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _getDepartment($path = [], $params = []){$department_id = $path['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 批量获取部门信息* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _batchGetDepartment($params = []){$department_ids = $params['department_ids'] ?? '';if (empty($department_ids)) return $this->error('部门ID不能为空');$url = $this->domain."/contact/v3/departments/batch?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 获取子部门列表* @param $path* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _getDepartmentChildren($path = [], $params = []){$department_id = $path['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}/children?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 获取父部门信息* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _getDepartmentParent($params = []){$department_id = $params['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}/parent?".http_build_query($params);$res = $this->httpCurl($url,'','GET');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 更新部门ID* @param $path* @param $params* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 18:31*/public function _updateDepartmentId($path = [], $params = [], $data = []){$department_id = $path['department_id'] ?? '';if (empty($department_id)) return $this->error('部门ID不能为空');$department_id = $data['new_department_id'] ?? '';if (empty($department_id)) return $this->error('新部门ID不能为空');$url = $this->domain."/contact/v3/departments/{$department_id}/update_department_id?".http_build_query($params);$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 创建角色* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 19:50*/public function _createRole($data = []){if (empty($data['role_name'] ?? '')) return $this->error('角色名称不能为空');$url = $this->domain.'/contact/v3/functional_roles';$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 修改角色名称* @param $path* @param $data* @return array|mixed* @author 陈龙* @date 2024-01-09 19:54*/public function _updateRoleName($path = [], $data = []){$role_id = $path['role_id'] ?? '';if (empty($role_id)) return $this->error('角色ID不能为空');if (empty($data['role_name'] ?? '')) return $this->error('角色名称不能为空');$url = $this->domain."/contact/v3/functional_roles/{$role_id}";$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 删除角色* @param $path* @return array|mixed* @author 陈龙* @date 2024-01-09 19:54*/public function _deleteRole($path = []){$role_id = $path['role_id'] ?? '';if (empty($role_id)) return $this->error('角色ID不能为空');$url = $this->domain."/contact/v3/functional_roles/{$role_id}";$res = $this->httpCurl($url,'','DELETE');$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}/*** @desc 发送消息* @param $path* @param $params* @return array|mixed* @author 陈龙* @date 2024-01-09 20:13*/public function _messages($params = [], $data = []){$receive_id = $data['receive_id'] ?? '';if (empty($receive_id)) return $this->error('receive_id不能为空');$url = "https://open.feishu.cn/open-apis/im/v1/messages?".http_build_query($params);$res = $this->httpCurl($url,$data);$res = json_decode($res,true);if (empty($res)) return $this->error('返回异常');return $res;}
}
service调用:
<?php
// +----------------------------------------------------------------------
// | 消息发送脚本服务层
// +----------------------------------------------------------------------
// | Copyright (c) 2020 http://www.jeoshi.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: 陈龙
// +----------------------------------------------------------------------namespace app\command\message\service;use app\common\model\Message;
use app\common\model\Users;
use app\common\model\UsersMessages;
use feishu\Api;
use think\Cache;
use think\Config;
use think\console\Output;
use think\QueueAmqp;class FeishuService extends Base
{protected $id;protected $to_third_id;protected $msg_type;protected $msg_type_attr;protected $msg_title;protected $msg_content;protected $uuid;/*** @var null 单列对象*/public static $instance = null;/*** 输出对象* @var Output*/public $output;public function __construct(){$this->output = new Output();}/*** @desc 陈龙* @return static|null* @author 陈龙* @date 2023-03-28 14:10*/public static function instance(){if (is_null(self::$instance)) {self::$instance = new static;}return self::$instance;}/*** @desc 发送信息* @param $message* @return array* @author 陈龙* @date 2024-08-14 13:36*/public function send($message = []){$this->id = $message['id'] ?? '';$this->uuid = $message['uuid'] ?? '';$this->to_third_id = $message['to_third_id'] ?? 0;$this->msg_type = $this->typeAttr($message['msg_type'] ?? 1);$this->msg_type_attr = $message['msg_type_attr'] ?? 0;$this->msg_title = $message['msg_title'] ?? '';$msg_content = $message['msg_content'] ?? '';$this->msg_content = $this->msg_type == 'text' ? $msg_content : json_decode($msg_content, true);$this->msg_content = $this->contentAttr();$msg_data = ['receive_id' => $this->to_third_id,'msg_type' => $this->msg_type,'content' => json_encode($this->msg_content),'uuid' => md5($this->id . "|" . $this->uuid)];$feishuApi = new Api(['company_id' => $message['company_id'] ?? 0]);$res = $feishuApi->messages($msg_data);$code = $res['code'] ?? '';if ($code != 0) return back(0, $res['msg'] ?? '');return back(1, '发送成功');}/*** @desc 消息类型转换* @param $type* @return string* @author 陈龙* @date 2024-08-13 14:49*/private function typeAttr($type = 1){switch ($type){case 1:$type_name = 'text'; //文本break;case 2:$type_name = 'interactive'; //卡片break;default:$type_name = 'text';break;}return $type_name;}/*** @desc 内容类型转换* @param $content* @return string* @author 陈龙* @date 2024-08-13 14:49*/private function contentAttr(){switch ($this->msg_type){case 'text':return $this->textAttr();case 'interactive':return $this->cardAttr();}}/*** @desc 文本转换* @return string* @author 陈龙* @date 2024-08-13 14:49*/private function textAttr(){$data[$this->msg_type] = $this->msg_content;return $data;}/*** @desc 卡片转换* @return array|null* @author 陈龙* @date 2024-08-20 19:45*/private function cardAttr(){switch ($this->msg_type_attr){case 1:return $this->cardTask();default:return $this->msg_content;}}/*** @desc 任务类卡片消息(审核/处理)* @return array* @author 陈龙* @date 2024-08-20 19:45*/private function cardTask(){$data = ['config' => ['wide_screen_mode' => true],'header' => ['template' => 'turquoise','title' => ['content' => $this->msg_title,'tag' => 'plain_text',],],'elements' => $this->cardTaskAttr()];return $data;}/*** @desc 卡片任务转换* @return array* @author 陈龙* @date 2024-08-14 17:51*/private function cardTaskAttr(){// 内容$elements = $this->_handleElements();// 操作$actions = $this->_handleActions();if (!empty($actions)){$elements[] = ['actions' => $actions,'tag' => 'action',];}return $elements;}/*** @desc 处理操作* @return array* @author 陈龙* @date 2024-08-20 17:43*/private function _handleActions(){$actions = [];$temp_actions = $this->msg_content['actions'] ?? [];foreach ($temp_actions as $action){$actions[] = ['tag' => 'button','text' => ['content' => $action['content'],'tag' => 'plain_text',],'type' => 'button','url' => $action['url'],];}return $actions;}/*** @desc 处理元素* @return array* @author 陈龙* @date 2024-08-20 17:44*/private function _handleElements(){$elements = [];$temp_elements = $this->msg_content['elements'] ?? [];foreach ($temp_elements as $item){$columns = $item['columns'] ?? [];if (empty($columns)) {// 单行$lable = $item['lable'] ?? '';$content = $item['content'] ?? '';$elements[] = ['tag' => 'markdown','content' => "**{$lable}:**\n{$content}",'text_align' => 'left','text_size' => 'normal',];}else{$columns_elements = [];// 多行foreach ($columns as $column){$lable = $column['lable'] ?? '';$content = $column['content'] ?? '';$columns_elements[] = ["tag" => "column","width" => "weighted","vertical_align" => "top","vertical_spacing" => "8px","background_style" => "default","elements" => [["tag" => "markdown","content" => "**{$lable}:**\n{$content}","text_align" => "left","text_size" => "normal"]],"weight" => 1];}$elements[] = ["tag" => "column_set","flex_mode" => "stretch","background_style" => "default","horizontal_spacing" => "8px","horizontal_align" => "left","columns" => $columns_elements,"margin" => "16px 0px 0px 0px"];}}return $elements;}
}
相关文章:
飞书API
extend目录下,API <?php // ---------------------------------------------------------------------- // | 飞书API // ---------------------------------------------------------------------- // | COPYRIGHT (C) 2021 http://www.jeoshi.com All rights reserved. …...
深入解析 Hydra 库:灵活强大的 Python 配置管理框架
深入解析 Hydra 库:灵活强大的 Python 配置管理框架 在机器学习、深度学习和复杂软件开发项目中,管理和维护大量的配置参数是一项具有挑战性的任务。传统的 argparse、json 或 yaml 方式虽然能管理部分配置,但随着项目规模的增长,…...

【开源免费】基于Vue和SpringBoot的失物招领平台(附论文)
本文项目编号 T 243 ,文末自助获取源码 \color{red}{T243,文末自助获取源码} T243,文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…...
科普:你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP;两个域名:localhost和host.docker.internal
三个IP 你的笔记本电脑中有三个IP:127.0.0.1、无线网 IP 和局域网 IP。 在不同的场景下,需要选用不同的 IP 地址,如下为各自的特点及适用场景: 127.0.0.1(回环地址) 特点 127.0.0.1 是一个特殊的 IP 地…...
测试WSS服务器
必须有域名,证书也是强制关联这个域名,阿里云、腾讯云、百度云都可以申请免费的证书,外网对应的主机要备案到域名 备案:是针域名下的主机备案,不备案的话,会强制断网 这个网站可以测试本地WSS连接 …...

unity学习49:寻路网格链接 offMeshLinks, 以及传送门效果
目录 1 网格链接 offMeshLinks 功能入口 1.1 unity 2022之前 1.2 unity 2022之后 2 网格链接 offMeshLinks 功能设置 3 点击 offMeshLinks 功能里的bake 3.1 unity 2022之前 3.2 unity 2022之后 3.3 实测link 3.4 跳跃距离增大,可以实现轻功类的效果 4 …...

Web 开发中的 5 大跨域标签解析:如何安全地进行跨域请求与加载外部资源
在 Web 开发中,跨域(Cross-Origin)是指从一个源(协议、域名、端口)访问另一个源的资源。以下是5个常见的用于跨域操作的 HTML 标签,它们主要用于跨域请求或加载外部资源:1. <script> 标签 用途:最常用于进行跨域请求的标签,特别是在 JSONP 技术中。浏览器允许通…...
UMLS数据下载及访问
UMLS数据申请 这个直接在官网上申请即可,记得把地址填全,基本都会拿到lisence。 UMLS数据访问 UMLS的数据访问分为网页访问,API访问以及数据下载后的本地访问,网页访问,API访问按照官网的指示即可,这里主…...
23种设计模式 - 空对象模式
模式定义 空对象模式(Null Object Pattern)是一种行为型设计模式,通过用无操作的空对象替代null值,消除客户端对空值的检查,避免空指针异常。其核心是让空对象与真实对象实现相同接口,但空对象不执行实际逻…...

Redis三剑客解决方案
文章目录 缓存穿透缓存穿透的概念两种解决方案: 缓存雪崩缓存击穿 缓存穿透 缓存穿透的概念 每一次查询的 key 都不在 redis 中,数据库中也没有。 一般都是属于非法的请求,比如 id<0,比如可以在 API 入口做一些参数校验。 大量访问不存…...
大学本科教务系统设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点
以下是大学本科教务系统的设计方案,涵盖需求分析、架构设计、核心模块和技术实现要点: 大学本科教务系统设计方案 一、需求分析 1. 核心用户角色 角色功能需求学生选课/退课、成绩查询、课表查看、学分统计、考试报名、学业预警教师成绩录入、课程大纲上传、教学进度管理、…...

Docker Mysql 数据迁移
查看启动命令目录映射 查看容器名称 docker ps查看容器的启动命令 docker inspect mysql8.0 |grep CreateCommand -A 20如下图所示:我这边是把/var/lib/mysql 目录映射到我宿主机的/mnt/mysql/data目录下,而且我的数量比较大使用方法1的话时间比较久,所以我采用方法2 如果没…...

ubuntu22.04离线安装K8S
1. 准备离线安装包 参考教程离线包准备教程 2. 准备环境 2.1. 准备主机 主机名ip系统k8s-master192.168.38.128ubuntu22.04k8s-node192.168.38.131ubuntu22.04 2.2. 设置host 修改 /etc/hosts 文件,添加master和node节点,需要和主机名保持一致 2…...
微信小程序中将图片截图为正方形(自动居中)
没啥可说的,直接看代码吧(邪恶的微信小程序和浏览器的还不一样) //将用户图片自动剪切成正方形 const cutImgToSquare (imgPath: string) > {//ts-ignorewx.createSelectorQuery().select(#canvas).fields({ node: true, size: true }).…...

传统的自动化行业的触摸屏和上位机,PLC是否会被取代?
传统的自动化行业的触摸屏和上位机是否会被取代? 在工业自动化领域,触摸屏和上位机长期扮演着核心角色,尤其在污水处理、化工生产等场景中,它们通过实时数据采集、逻辑控制、报警联动等功能,保障了生产设备的稳定运行…...

【论文精读】VLM-AD:通过视觉-语言模型监督实现端到端自动驾驶
论文地址: VLM-AD: End-to-End Autonomous Driving through Vision-Language Model Supervision 摘要 人类驾驶员依赖常识推理来应对复杂多变的真实世界驾驶场景。现有的端到端(E2E)自动驾驶(AD)模型通常被优化以模仿…...

2024年数字政府服务能力优秀创新案例汇编(附下载)
12月19日,由中国电子信息产业发展研究院指导、中国软件评测中心主办的“2024数字政府评估大会”在北京召开,大会主题是:为公众带来更好服务体验。 会上,中国软件评测中心副主任吴志刚发布了2024年数字政府服务能力评估结果&#…...
Ollama Docker 镜像部署
文章来源:Docker 部署文档 -- Ollama 中文文档|Ollama官方文档 仅 CPU docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama英伟达 GPU 安装 NVIDIA Container Toolkit。 使用 Apt 安装 配置存储库 curl -fsSL https://nvidia.g…...

[深度学习][python]yolov12+bytetrack+pyqt5实现目标追踪
【算法介绍】 实时目标检测因其低延迟特性而持续受到广泛关注,具有重要的实际应用价值[4, 17, 24, 28]。其中,YOLO系列[3, 24, 28, 29, 32, 45-47, 53, 57, 58]通过有效平衡延迟与精度,在该领域占据主导地位。尽管YOLO的改进多集中在损失函数…...
【深度学习】矩阵的理解与应用
一、矩阵基础知识 1. 什么是矩阵? 矩阵是一个数学概念,通常表示为一个二维数组,它由行和列组成,用于存储数值数据。矩阵是线性代数的基本工具之一,广泛应用于数学、物理学、工程学、计算机科学、机器学习和数据分析等…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

HBuilderX安装(uni-app和小程序开发)
下载HBuilderX 访问官方网站:https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本: Windows版(推荐下载标准版) Windows系统安装步骤 运行安装程序: 双击下载的.exe安装文件 如果出现安全提示&…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...