当前位置: 首页 > news >正文

飞书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. …...

杨校老师课堂之信息学奥赛结构体操作使用经典题集锦汇总

C基础:结构体数组综合训练 员工信息处理系统题目描述输入描述输出描述解题思路参考代码 员工信息处理系统 题目描述 在一家企业中&#xff0c;员工信息的准确性和时效性是日常人事管理工作的关键。由于企业员工数量众多&#xff0c;手动统计与更新员工信息不仅耗费大量时间&a…...

交互编程工具之——Jupyter

Jupyter 是什么&#xff1f; Jupyter 是一个开源的交互式编程和数据分析工具&#xff0c;广泛应用于数据科学、机器学习、教育和研究领域。其核心是 Jupyter Notebook&#xff08;现升级为 JupyterLab&#xff09;&#xff0c;允许用户在一个基于浏览器的界面中编写代码、运行…...

Redis常见问题排查

redis连接不上去&#xff0c;ERR max number of clients reached redis默认最大连接是10000&#xff0c;如果出现连接泄露或者被服务器被攻击可能会出现连接数超过限制。 Redis 的 INFO 命令可以提供服务器的统计信息&#xff0c;其中包括当前客户端连接数。这是获取连接数最…...

Hadoop初体验

一、HDFS初体验 1. shell命令操作 hadoop fs -mkdir /itcast hadoop fs -put zookeeper.out /itcast hadoop fs -ls / 2. Web UI页面操作 结论&#xff1a; HDFS本质就是一个文件系统有目录树结构 和Linux类似&#xff0c;分文件、文件夹为什么上传一个小文件也这…...

深入解析C++26 Execution Domain:设计原理与实战应用

一、Domain设计目标与核心价值 Domain是C26执行模型的策略载体&#xff0c;其核心解决两个问题&#xff1a; 执行策略泛化&#xff1a;将线程池、CUDA流等异构调度逻辑抽象为统一接口策略组合安全&#xff1a;通过类型隔离避免不同执行域的策略污染 // Domain类型定义示例&a…...

基于Flask的租房信息可视化系统的设计与实现

【Flask】基于Flask的租房信息可视化系统的设计与实现&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 随着互联网的快速发展&#xff0c;租房市场日益繁荣&#xff0c;信息量急剧增加&#xff…...

TensorFlow v2.16 Overview

TensorFlow v2.16 Overview 一、模块 Modules二、类 Classes三、函数 Functions TensorFlow v2.16.1 Overview 一、模块 Modules 模块是TensorFlow中组织代码的一种方式&#xff0c;将相关的功能和类封装在一起&#xff0c;方便用户使用和管理。每个模块都提供了特定领域的公共…...

网页版的俄罗斯方块

1、新建一个txt文件 2、打开后将代码复制进去保存 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>俄…...

Vue3 状态管理 - Pinia

目录 1. 什么是Pinia 2. 手动添加Pinia到Vue项目 3. Pinia的基础使用 4. getters实现 5. action异步实现 6. storeToRefs工具函数 7. Pinia的调试 8. Pinia的持久化插件 1. 什么是Pinia Pinia 是 Vue 专属的最新状态管理库 &#xff0c;是 Vuex 状态管理工具的替代品 …...

Arduino 第十六章:pir红外人体传感器练习

Arduino 第十六章&#xff1a;PIR 传感器练习 一、引言 在 Arduino 的众多有趣项目中&#xff0c;传感器的应用是非常重要的一部分。今天我们要学习的主角是 PIR&#xff08;被动红外&#xff09;传感器。PIR 传感器能够检测人体发出的红外线&#xff0c;常用于安防系统、自动…...

伯克利 CS61A 课堂笔记 10 —— Trees

本系列为加州伯克利大学著名 Python 基础课程 CS61A 的课堂笔记整理&#xff0c;全英文内容&#xff0c;文末附词汇解释。 目录 01 Trees 树 Ⅰ Tree Abstraction Ⅱ Implementing the Tree Abstraction 02 Tree Processing 建树过程 Ⅰ Fibonacci tree Ⅱ Tree Process…...

Springboot 高频面试题

以下是Spring Boot的高频面试题及答案和底层原理解释&#xff1a; 基础概念 什么是Spring Boot&#xff0c;其主要特点是什么&#xff1f; 答案&#xff1a; Spring Boot本质上是一个建立在Spring框架之上的快速应用开发框架。其主要特点包括&#xff1a; 启动器&#xff1a;一…...

从零开始玩转TensorFlow:小明的机器学习故事 2

你好&#xff0c;TensorFlow&#xff01;——从零开始的第一个机器学习程序 1. 为什么要写这个“Hello, TensorFlow!”&#xff1f; 无论学习什么新语言或新框架&#xff0c;“Hello World!”示例都能帮助我们快速确认开发环境是否就绪&#xff0c;并掌握最基本的使用方式。对…...

第四届图像、信号处理与模式识别国际学术会议(ISPP 2025)

重要信息 会议官网&#xff1a;www.icispp.com 会议时间&#xff1a;2025年3月28-30日 会议地点&#xff1a;南京 简介 由河海大学和江苏大学联合主办的第四届图像、信号处理与模式识别国际学术会议&#xff08;ISPP 2025) 将于2025年3月28日-30日在中国南京举行。会议主…...

阿里云通过docker安装skywalking及elasticsearch操作流程

系统 本文使用系统为 Alibaba Cloud Linux 3.2104 LTS 64位 配置为 4核8G PS&#xff1a;最低配置应为2核4G&#xff0c;配置过低无法启动 安装docker 1.卸载旧版本docker yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-…...

Linux·spin_lock的使用

自旋锁 内核当发生访问资源冲突的时候&#xff0c;可以有两种锁的解决方案选择&#xff1a; 一个是原地等待一个是挂起当前进程&#xff0c;调度其他进程执行&#xff08;睡眠&#xff09; Spinlock 是内核中提供的一种比较常见的锁机制&#xff0c;自旋锁是“原地等待”的方…...

企业内部真题

文章目录 前端面试题:一个是铺平的数组改成树的结构问题一解析一问题一解析二前端面试题:for循环100个接口,每次只调3个方法一:使用 `async/await` 和 `Promise`代码解释(1):代码解释(2):1. `fetchApi` 函数2. `concurrentFetch` 函数3. 生成 100 个接口地址4. 每次并…...

MySQL基本操作——包含增删查改(环境为Ubuntu20.04,MySQL5.7.42)

1.库的操作 1.1 创建数据库 语法&#xff1a; 说明&#xff1a; 大写的表示关键字 [] 是可选项 CHARACTER SET: 指定数据库采用的字符集 COLLATE: 指定数据库字符集的校验规则 1.2 创建案例 创建一个使用utf8字符集的db1数据库 create database db1 charsetutf8; …...

程序代码篇---Python指明函数参数类型

文章目录 前言简介一、函数参数的类型指定1. 基本类型提示2. 默认参数3. 可变参数4. 联合类型&#xff08;Union&#xff09;5. 可选类型&#xff08;Optional&#xff09;6. 复杂类型 二、返回值的类型指定1. 基本返回类型2. 无返回值&#xff08;None&#xff09;3. 返回多个…...

AIGC视频扩散模型新星:SVD——稳定扩散的Video模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍慕尼黑大学携手 NVIDIA 等共同推出视频生成模型 Video LDMs。NVIDIA 在 AI 领域的卓越成就家喻户晓&#xff0c;而慕尼黑大学同样不容小觑&#xff0c;…...

MySql面试宝典【刷题系列】

文章目录 一、Mysql 的存储引擎 myisam 和 innodb 的区别。二、MySQL数据库作发布系统的存储&#xff0c;一天五万条以上的增量&#xff0c;预计运维三年,怎么优化&#xff1f;三、对于大流量的网站,您采用什么样的方法来解决各页面访问量统计问题&#xff1f;四、锁的优化策略…...

银河麒麟系统安装mysql5.7【亲测可行】

一、安装环境 cpu&#xff1a;I5-10代&#xff1b; 主板&#xff1a;华硕&#xff1b; OS&#xff1a;银河麒麟V10&#xff08;SP1&#xff09;未激活 架构&#xff1a;Linux 5.10.0-9-generic x86_64 GNU/Linux mysql版本&#xff1a;mysql-5.7.34-linux-glibc2.12-x86_64.ta…...

CTF-内核pwn入门1: linux内核模块基础原理

本文由A5rZ在2025-2-18-21:00编写 1.可加载内核模块是什么&#xff1f; 内核可加载模块&#xff08;*.ko 文件&#xff09;是内核的一种扩展机制&#xff0c;可以在不重启系统的情况下加载和卸载代码。它们允许动态地向内核添加新的功能或支持。 以下是一些内核模块常见的功能&…...

第4章 4.1 Entity Framework Core概述

4.1.1 什么是ORM ORM (object tralstional mapping ,对象关系映射)中的“对象”指的就是C#中的对象&#xff0c;而“关系”是关系型数据库&#xff0c;“映射”指搭建数据库与C#对象之间的“桥梁”。 比如使用ORM &#xff0c;可以通过创建C#对象的方式把数据插入数据库而不需…...

【C语言】自定义类型:联合体和枚举

1. 联合体 1.1 联合体类型的声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以是不同的类型。 但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫&#xff1a;共用体。 给联合…...

企业组网IP规划与先关协议分析

目录 一、IP编址 1、IP地址组成 2、IP地址表达 3、IP 地址分类 4、IP地址类型 5、IP网络通信 6、子网掩码 7、默认子网掩码 8、IP 地址规划 9、有类IP编制缺陷 10、VLSM 11、变长子网掩码案例 12、网关 13、无类域间路由 一、IP编址 网络层位于数据链路层与传输层之间…...

数据结构之【顺序表简介】

1.顺序表的概念 顺序表 是 用一段物理地址连续的存储单元 依次 存储数据元素的线性结构 一般情况下采用数组存储 2.顺序表的结构 既然顺序表可以用来存储数据元素&#xff0c; 那就少不了 增删查改 的操作 此时&#xff0c;单一地只创建数组满足不了上述操作 创建相应的结构…...

如何调用 DeepSeek API:详细教程与示例

目录 一、准备工作 二、DeepSeek API 调用步骤 1. 选择 API 端点 2. 构建 API 请求 3. 发送请求并处理响应 三、Python 示例&#xff1a;调用 DeepSeek API 1. 安装依赖 2. 编写代码 3. 运行代码 四、常见问题及解决方法 1. API 调用返回 401 错误 2. API 调用返回…...

一周学会Flask3 Python Web开发-flask3模块化blueprint配置

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们在项目开发的时候&#xff0c;多多少少会划分几个或者几十个业务模块&#xff0c;如果把这些模块的视图方法都写在app.py…...

vxe-table实现动态列

vxe-table实现动态列 1.动态列解释2.解决步骤2.1将后端返回的动态列表头&#xff0c;按照格式拼接在固定列表头上2.2将后端返回的列表数据按照键值对格式组装 1.动态列解释 正常列表是有固定的列&#xff1b;我的需求是&#xff0c;最初只知道表格的固定两列&#xff0c;查询数…...

day16_推荐系统和总结

文章目录 day16_推荐系统和总结一、推荐实现1、基于流行度推荐&#xff08;掌握&#xff09;1.1 近期热门商品推荐1.2 个人热门商品推荐 2、基于隐语义模型的协同过滤推荐&#xff08;了解&#xff09;2.1 ALS算法介绍2.2 推荐代码 3、基于物品的协同过滤推荐&#xff08;了解&…...

Scifinder数据库专利检索实操教程

在上期的内容里&#xff0c;我为大家分享了查询专利的数据库。发出后有小伙伴问&#xff0c;怎么没有大佬Scifinder&#xff01;这不&#xff0c;应大家的呼声&#xff0c;今天就来给大家好好讲讲 Scifinder专利检索&#xff01;&#xff01; SciFinder&#xff0c;由美国化学会…...

Linux下 <用户名> is not in the sudoers file

参考链接 https://blog.csdn.net/weixin_49192027/article/details/114702099 原因 当前的用户没有加入到sudo的配置文件里 解决方案 切换到root用户 su 编辑配置文件 vim /etc/sudoers 如果没有安装vim 运行命令 sudo apt-get install vim vim的使用教程 参考链接…...

Linux下基本指令(4)

Linux权限的概念 Linux下有两种用户&#xff1a;超级用户&#xff08;root&#xff09;、普通用户。 超级用户&#xff1a;可以再linux系统下做任何事情&#xff0c;不受限制 普通用户&#xff1a;在linux下做有限的事情。 超级用户的命令提示符是“#”&#xff0c;普通用户…...

【算法与数据结构】字典树(Trie)详解

目录 一&#xff0c;字典树的定义 二&#xff0c;字典树的代码实现 完整代码详细注释&#xff1a; 测试用例测试结果&#xff1a; 三&#xff0c;处理其他字符 四&#xff0c;内存优化与扩展 1. 内存优化 2. 扩展功能 五&#xff0c;扩展功能支持通配符匹配 六&…...

el-table树状表格,默认展开第一个节点的每一层

效果如图 <template><el-table:data"tableData"style"width: 100%":tree-props"{ children: children, hasChildren: hasChildren }":expand-row-keys"expandRowKeys"row-key"id"expand-change"handleExpan…...

RPA-实例(UiPath )

UiPath 是一个流行的机器人流程自动化(RPA)工具,用于自动化重复性任务。以下是一个简单的实例,展示如何使用 UiPath 自动化一个常见的任务:从 Excel 文件中读取数据并将其输入到网页表单中。 实例:从 Excel 读取数据并自动填写网页表单 步骤 1:准备工作 安装 UiPath S…...

【RabbitMQ业务幂等设计】RabbitMQ消息是幂等的吗?

在分布式系统中&#xff0c;RabbitMQ 自身不直接提供消息幂等性保障机制&#xff0c;但可通过业务逻辑设计和技术组合实现消息处理的幂等性。以下是 8 种核心实现方案及最佳实践&#xff1a; 一、消息唯一标识符 (Message Deduplication) 原理 每条消息携带全局唯一ID&#xff…...

Spring Boot项目开发常见问题及解决方案(上)

启动相关问题 问题 1&#xff1a;项目启动时报错“找不到主类” 在使用 Spring Boot 打包成可执行 JAR 文件后启动&#xff0c;有时会遇到这个头疼的问题。通常是因为打包配置有误或者项目结构不符合要求。 解决方案&#xff1a; 首先&#xff0c;检查 pom.xml&#xff08;Ma…...

具有整合各亚专科医学领域知识能力的AI智能体开发纲要(2025版)

整合各亚专科医学领域知识能力的AI代理的开发与研究 一、引言 1.1 研究背景 在科技飞速发展的当下,人工智能(AI)已成为推动各行业变革的关键力量,医疗领域也不例外。近年来,AI 在医疗行业的应用取得了显著进展,从医学影像诊断到疾病预测,从药物研发到个性化医疗,AI 技…...

Selenium实战案例1:论文pdf自动下载

在上一篇文章中&#xff0c;我们介绍了Selenium的基础用法和一些常见技巧。今天&#xff0c;我们将通过中国科学&#xff1a;信息科学网站内当前目录论文下载这一实战案例来进一步展示Selenium的web自动化流程。 目录 中国科学&#xff1a;信息科学当期目录论文下载 1.网页内…...

进程的介绍--进程状态/切换

1.冯 • 诺依曼体系结构 1.1 体系结构 冯•诺依曼结构也称普林斯顿结构&#xff0c;是一种将程序指令存储器和数据存储器合并在一起的存储器结构。数学家冯•诺依曼提出了计算机制造的三个基本原则&#xff0c;即采用二进制逻辑、程序存储执行以及计算机由五个部分组成&#x…...

一文详解U盘启动Legacy/UEFI方式以及GPT/MBR关系

对于装系统的老手而说一直想研究一下装系统的原理&#xff0c;以及面对一些问题时的解决思路&#xff0c;故对以前的方法进行原理上的解释&#xff0c;主要想理解其底层原理。 引导模式 MBR分区可以同时支持UEFI和Legacy引导&#xff0c;我们可以看一下微pe制作的启动盘&#…...

【面试】Redis 常见面试题

一、介绍一下什么是 Redis&#xff0c;有什么特点? Redis 是一个高性能的 key-value 内存数据库。 不同于传统的 MySQL 这样的关系型数据库&#xff0c;Redis 主要使用内存存储数据&#xff08;当然也支持持久化存储到硬盘上&#xff09;&#xff0c;并非是使用 “表” 这样…...

扩散模型中,Flow Matching的训练方式相比于 DDPM 训练方法有何优势?

在扩散模型中,Flow Matching(FM)相比DDPM(Denoising Diffusion Probabilistic Models)的训练方法具有以下核心优势: 1. 更简单的训练目标 DDPM:通过逐步预测噪声来间接优化数据分布的变分下界(ELBO),需要设计多步的噪声调度策略,训练目标依赖马尔可夫链的分解。Flow…...

Unity FBXExport导出的FBX无法在Blender打开

将FBX转换为obj&#xff1a; Convert 3D models online - free and secure...

【无标题】基于Unity写一个DelayInvoke方法

没想到来得这么块,程序员可能比司机先失业了。。。。。。。。 //测试过一定要这么调用??奇怪的是,不能(mono 直接引用)??///但AI还是给出了能用的代码 MonoBehaviourExtensions.DelayInvoke(this,()=> { },3); /* 方案一,使用示例(): public class ExampleUsag…...

JavaScript 语言基础之标签语句

标签语句的语法 label: statement label 表示标签名&#xff0c;可以是任何合法的标识符&#xff0c;但不能是 JavaScript 中的保留字。statement 表示被标记的语句块&#xff0c;可以是任何合法的 JavaScript 语句。 用法 标签语句的主要用途是在代码中进行跳转&#xff0…...

【网络编程】网络编程基础:TCP/UDP 协议

一、什么是网络&#xff1f; 网络是信息传输&#xff0c;接收和共享的虚拟世界&#xff0c;通过把网络上的信息汇聚在一起&#xff0c;将这些资源进行共享。 初衷&#xff1a;知识共享。这里不得不提到Internet 的历史&#xff0d;它其实是“冷战”的产物&#xff1a; 1957年…...