$token]]; $config = config("dingtalk.{$type}"); if(empty($config)) return [false, '钉钉配置信息不存在']; $appKey = $config['app_key'] ?? null; $appSecret = $config['app_secret'] ?? null; if (!$appKey) return [false, 'AppKey 配置不完整']; if (!$appSecret) return [false, 'AppSecret 配置不完整']; $url = "https://api.dingtalk.com/v1.0/oauth2/accessToken"; $resp = $this->curlOpen1($url, [ 'request' => 'post', 'header' => ['Content-Type: application/json'], 'json' => [ "appKey" => $appKey, "appSecret" => $appSecret ] ]); $res = json_decode($resp, true); $accessToken = $res['accessToken'] ?? ""; $expires_in = $res['expires_in'] ?? 0; if(empty($accessToken)) return [false, 'AccessToken获取失败']; Redis::setex($key, $expires_in, $accessToken); return [true, ['access_token' => $accessToken]]; } /** * 根据前端传来的免登 code 获取用户信息 * @param string $code 前端 dd.getAuthCode 获取的 code * @return array [bool, data] bool 表示成功与否,data 成功返回用户信息,失败返回错误信息 */ public function getUserByCode($data, $LoginType) { if(empty($LoginType)) return [false, 'login_type类型不能为空']; if(! isset(DDEmployee::type[$LoginType])) return [false, 'login_type类型不存在或错误']; $code = $data['code'] ?? ""; if (empty($code)) return [false, '钉钉授权code不能为空']; // 1. 获取 access_token [$success, $tokenData] = $this->getAccessToken($LoginType); if (! $success) return [false, $tokenData]; // tokenData 是错误信息 $accessToken = $tokenData['access_token']; // 2. 用 code 换取用户信息(v2 接口) $url = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo?access_token={$accessToken}"; $resp = $this->curlOpen1($url, [ 'request' => 'post', 'header' => [ "Content-Type: application/json", ], 'json' => [ "code" => $code ] ]); $res = json_decode($resp, true); if (!isset($res['errcode'])) { return [false, '接口返回异常: ' . $resp]; } if ($res['errcode'] !== 0) { return [false, '获取用户信息失败: ' . $res['errmsg']]; } if(! empty($res['result'])){ $result = $res['result']; DDEmployee::updateOrCreate( ['userid' => $result['userid'], 'login_type' => $LoginType], ['name' => $result['name'], 'userid' => $result['userid'], 'login_type' => $LoginType, 'u_userid' => $result['unionid']] ); } return [true, $res]; } private function getManDetail($user, $accessToken){ // 3. 根据 userid 获取详细用户信息(包括部门) $urlDetail = "https://oapi.dingtalk.com/topapi/v2/user/get?access_token={$accessToken}"; $respDetail = $this->curlOpen1($urlDetail, [ 'request' => 'post', 'header' => ["Content-Type: application/json"], 'json' => ["userid" => $user['userid']] ]); $detail = json_decode($respDetail, true); if (!isset($detail['errcode'])) return [false, '获取用户详情接口异常: ' . $respDetail]; if ($detail['errcode'] !== 0) return [false, '获取用户详情失败: ' . $detail['errmsg']]; if (empty($detail['result'])) return [false, '获取用户详情失败,结果为空']; // 返回完整用户信息 return [true, $detail['result']]; } public function createProcessInstance($data, $user) { if(empty($data['type'])) return [false, '单据类型不能为空']; $type = $data['type']; if(empty($data['order_number'])) return [false,'单号不能为空']; [$success, $msg] = $this->checkCreateProcessInstance($data, $user); if(! $success) return [false, $msg]; //获取模板id $code = $this->getModelCode($type, $user); //获取模板数据 [$success, $formData] = $this->getFormData($data, $user); if(! $success) return [false, $formData]; // 1. 获取 access_token [$success, $tokenData] = $this->getAccessToken($user['login_type']); if (!$success) return [false, $tokenData]; $accessToken = $tokenData['access_token']; $userId = $user['userid']; [$success, $userDetail] = $this->getManDetail($user, $accessToken); if(!$success) return [false, $userDetail]; //创建审批 [$success, $msg] = $this->createFlow($accessToken, $code, $userId, $userDetail, $formData); if(! $success) return [false, $msg]; //记录信息 $this->recordDatabase($data, $user, $msg); return [true, '']; } private function recordDatabase($data, $user, $process_instance_id){ $type = $data['type']; Record::insert([ 'type' => $type, 'login_type' => $user['login_type'], 'database' => $user['zt_database'], 'userid' => $user['userid'], 'order_number'=> $data['order_number'], 'crt_time' => time(), 'process_instance_id' => $process_instance_id, 'state' => Record::state_zero ]); //保证 U8State::updateOrCreate( ['order_number' => $data['order_number'], 'login_type' => $user['login_type'], 'type' => $type], ['state' => U8State::state_zero, 'userid' => $user['userid'],] ); return [true, '']; } private function checkCreateProcessInstance($data, $user){ list($status,$msg) = $this->limitingSendRequestBackgExpire($data['order_number'].$data['type'].$user['login_type']); if(! $status) return [false,$msg]; $type = $data['type']; $login_type = $user['login_type']; // // 1. 获取该单号最新的一条记录 // $lastRecord = Record::where('del_time', 0) // ->where('type', $type) // ->where('login_type', $login_type) // ->where('order_number', $data['order_number']) // ->latest('id') // 按 ID 倒序,取最新 // ->first(['state']); // 只取状态字段 // // // 2. 逻辑判断 // if ($lastRecord) { // $text_o = Record::type_name[$type]; // // 如果状态是 0 (待审核) 或 1 (审核通过),拦截 // if (in_array($lastRecord->state, [Record::state_zero, Record::state_one])) { // $text = Record::state_name[$lastRecord->state]; // return [false, $text_o . ' (' . $data['order_number'] . ') ' . $text . ',操作失败']; // } // } // 1. 获取该单号最新的一条记录 $lastRecord = U8State::where('del_time', 0) ->where('type', $type) ->where('login_type', $login_type) ->where('order_number', $data['order_number']) ->first(['state']); // 只取状态字段 // 2. 逻辑判断 if ($lastRecord) { $text_o = U8State::type_name[$type]; // 如果状态是 0 (待审核) 或 1 (审核通过),拦截 if (in_array($lastRecord->state, [U8State::state_zero, U8State::state_one])) { $text = U8State::state_name[$lastRecord->state]; return [false, $text_o . ' (' . $data['order_number'] . ') 处于' . $text . ',操作失败']; } } return [true, '']; } private function createFlow($accessToken, $code, $userId, $userDetail, $formData){ // 2. 请求 URL $url = "https://oapi.dingtalk.com/topapi/processinstance/create?access_token={$accessToken}"; // 3. 请求体 $payload = [ "process_code" => $code, // 审批模板编码 "originator_user_id" => $userId, // 发起人 userId "dept_id" => $userDetail['dept_id_list'][0], // 发起人部门 ID "form_component_values" => $formData, // 表单数据 ]; // 4. 发送请求 $resp = $this->curlOpen1($url, [ 'request' => 'post', 'header' => [ "Content-Type: application/json", ], 'json' => $payload ]); $res = json_decode($resp, true); if (!isset($res['errcode'])) { return [false, "接口返回异常: " . $resp]; } if ($res['errcode'] !== 0) { return [false, "创建审批实例失败: " . $res['errmsg']]; } return [true, $res['process_instance_id']]; } //待审核 public function getTodoProcessList1($data, $user) { // 1. 获取 AccessToken [$success, $tokenData] = $this->getAccessToken($user['login_type']); if (!$success) return [false, $tokenData]; $accessToken = $tokenData['access_token']; // 2. 请求 URL (使用 TOP 接口) $url = "https://oapi.dingtalk.com/topapi/processinstance/listids?access_token={$accessToken}"; // 3. 准备参数 // 注意:TOP 接口的分页叫 cursor (偏移量),从 0 开始 if(empty($data['page_index'])) { $cursor = 0; }else{ $cursor = ($data['page_index'] - 1) * $data['page_size']; } $payload = [ 'userid' => $user['userid'], 'cursor' => $cursor, 'size' => (int)($data['page_size'] ?? 20), 'process_code' => 'PROC-B31B268E-6B7E-417D-A103-8765D8AE9090' ]; // 4. 发送请求 $resp = $this->curlOpen1($url, [ 'request' => 'post', 'json' => $payload ]); $res = json_decode($resp, true); dd($res); // 5. 错误处理 (TOP 接口 errcode 为 0 表示成功) if (($res['errcode'] ?? -1) !== 0) { return [false, "获取待审批列表失败: " . ($res['errmsg'] ?? '未知错误')]; } $result = $res['result'] ?? []; $instanceIds = $result['list'] ?? []; $nextCursor = $result['next_cursor'] ?? null; $hasMore = !is_null($nextCursor); if (empty($instanceIds)) { return [true, ['list' => [], 'has_more' => false]]; } // 6. 关联本地业务记录 // 因为 TOP 接口只给实例 ID,不给 TaskID,如果你本地需要 TaskID, // 通常需要再通过单据详情接口获取,或者本地生成。 $records = Record::where('del_time', 0) ->whereIn('process_instance_id', $instanceIds) ->where('login_type', $user['login_type']) ->select('type', 'order_number', 'process_instance_id') ->get(); $finalList = []; foreach ($records as $item) { $finalList[] = [ 'type' => $item->type, 'type_title' => U8State::type_name[$item->type] ?? '未知', 'order_number' => $item->order_number, 'process_instance_id' => $item->process_instance_id, 'task_id' => '' // TOP 列表接口不直接返回 taskId ]; } return [true, [ 'list' => $finalList, 'has_more' => $hasMore ]]; } public function getTodoProcessList($data, $user) { [$success, $tokenData] = $this->getAccessToken($user['login_type']); if (!$success) return [false, $tokenData]; $accessToken = $tokenData['access_token']; $pageNumber = $data['page_index'] ?? 1; $pageSize = $data['page_size'] ?? 20; // 重点:加上 viewId=all $url = "https://api.dingtalk.com/v1.0/workflow/processCentres/todoTasks?userId={$user['userid']}&pageNumber=1&pageSize=20"; $url = "https://api.dingtalk.com/v1.0/workflow/processes/todoTasks/numbers?userId={$user['userid']}"; $resp = $this->curlOpen1($url, [ 'request' => 'get', 'header' => [ "Content-Type: application/json", "x-acs-dingtalk-access-token: {$accessToken}" ] ]); $res = json_decode($resp, true); if (isset($res['code']) && $res['code'] !== 'success') { return [false, "钉钉接口报错: " . ($res['message'] ?? '未知错误')]; } $result = $res['result'] ?? []; $tasks = $result['list'] ?? []; $hasMore = $result['hasMore'] ?? false; if (empty($tasks)) { return [true, ['list' => [], 'has_more' => $hasMore]]; } // 提取实例ID $instanceIds = array_column($tasks, 'processInstanceId'); // 建立 实例ID -> 任务ID 的映射 $taskMap = array_column($tasks, 'taskId', 'processInstanceId'); // 关联本地业务表记录 $records = Record::where('del_time', 0) ->whereIn('process_instance_id', $instanceIds) ->where('login_type', $user['login_type']) ->select('type', 'order_number', 'process_instance_id') ->get(); $finalList = []; foreach ($records as $item) { $finalList[] = [ 'type' => $item->type, 'type_title' => U8State::type_name[$item->type], 'order_number' => $item->order_number, 'process_instance_id' => $item->process_instance_id, 'task_id' => $taskMap[$item->process_instance_id] ?? '' ]; } return [true, [ 'list' => $finalList, 'has_more' => $hasMore ]]; } //审核 public function executeProcess($data, $user) { if(empty($data['result']) || ! in_array($data['result'], ['agree','refuse'])) return [false, 'result错误或不存在']; if(empty($data['task_id'])) return [false, 'task_id错误或不存在']; if(empty($data['process_instance_id'])) return [false, 'process_instance_id错误或不存在']; // 1. 获取 AccessToken [$success, $tokenData] = $this->getAccessToken($user['login_type']); if (!$success) return [false, $tokenData]; $accessToken = $tokenData['access_token']; // 2. 接口 URL (新版 v1.0 路径) $url = "https://api.dingtalk.com/v1.0/workflow/processInstances/execute"; // 3. 构建请求体 // 注意:taskId 必须从待办任务接口中获取,不能随意填写 $payload = [ "processInstanceId" => $data['process_instance_id'], // 审批实例 ID "actionerUserId" => $user['userid'], // 操作人钉钉 ID "result" => $data['result'], "remark" => $data['remark'] ?? '同意。', // 审批意见 "taskId" => $data['task_id'], ]; // 如果有图片或附件,则加入 file 字段 if (!empty($data['photos']) || !empty($data['attachments'])) { $payload['file'] = [ "photos" => $data['photos'] ?? [], "attachments" => $data['attachments'] ?? [] ]; } // 4. 发送请求 $resp = $this->curlOpen1($url, [ 'request' => 'post', 'header' => [ "Content-Type: application/json", "x-acs-dingtalk-access-token: {$accessToken}" ], 'json' => $payload ]); $res = json_decode($resp, true); // 5. 结果处理 // 新版接口成功时通常返回空对象或 {"result": true} if (isset($res['code']) && $res['code'] !== 'success') { return [false, "审批操作失败: " . ($res['message'] ?? '未知错误')]; } try { DB::beginTransaction(); // 成功后续业务逻辑 if(isset($res['success']) && $res['success'] == true) $this->updateDatabase($data, $user); DB::commit(); }catch (\Throwable $exception){ DB::rollBack(); return [false, $exception->getMessage()]; } return [true, ""]; } private function updateDatabase($data, $user){ $record = Record::where('login_type', $user['login_type']) ->where('process_instance_id') ->first(); if(empty($record)) return [false, 'record记录不存在']; $record = $record->toArray(); if($data['result'] == 'agree'){ //通过 Record::where('login_type', $user['login_type']) ->where('process_instance_id') ->update(['del_time' => 2]); ProcessDataJob::dispatch($record)->onQueue(Record::$job); }else{ //驳回 Record::where('login_type', $user['login_type']) ->where('process_instance_id') ->update(['del_time' => 1]); U8State::updateOrCreate( ['order_number' => $record['order_number'], 'login_type' => $user['login_type'], 'type' => $record['type']], ['state' => U8State::state_two] ); } return [true, '']; } public function executeApproval($data, $user) { [$success, $tokenData] = $this->getAccessToken($user['login_type']); if (!$success) return [false, $tokenData]; $accessToken = $tokenData['access_token']; $processInstanceId = $data['process_instance_id'] ?? 0; $action = $data['action'] ?? 'agree'; $remark = $data['remark'] ?? '同意'; // 1. 请求 URL $url = "https://oapi.dingtalk.com/topapi/process/instance/execute?access_token={$accessToken}"; // 2. 构造请求体 $payload = [ "process_instance_id" => $processInstanceId, "remark" => $remark, "result" => $action, // 'agree' 或 'refuse' "task_id" => $this->getTaskIdByInstanceId($accessToken, $processInstanceId, $user['userid']), // 获取当前人的任务ID ]; // 3. 发送请求 $resp = $this->curlOpen1($url, [ 'request' => 'post', 'header' => ["Content-Type: application/json"], 'json' => $payload ]); $res = json_decode($resp, true); if (!isset($res['errcode']) || $res['errcode'] !== 0) { return [false, "审批操作失败: " . ($res['errmsg'] ?? '未知错误')]; } return [true, ""]; } private function getTaskIdByInstanceId($accessToken, $instanceId, $userId) { $url = "https://oapi.dingtalk.com/topapi/processinstance/get?access_token={$accessToken}"; $resp = $this->curlOpen1($url, [ 'request' => 'post', 'header' => ["Content-Type: application/json"], 'json' => ["process_instance_id" => $instanceId] ]); $res = json_decode($resp, true); $tasks = $res['process_instance']['tasks'] ?? []; foreach ($tasks as $task) { // 状态为 RUNNING (进行中) 且 处理人是当前用户 if ($task['task_status'] === 'RUNNING' && $task['userid'] === $userId) { return $task['task_id']; } } return null; } private function getModelCode($type, $user){ $login_type = $user['login_type']; if($login_type == DDEmployee::type_one){ //浙江 if($type == 1){ // 采购单 $code = "PROC-B31B268E-6B7E-417D-A103-8765D8AE9090"; }elseif ($type == 2){ // 请购单 $code = "PROC-C2F6D31A-979F-4038-B2A7-F2295A71702B"; }elseif ($type == 3){ // 采购入库单 $code = "PROC-6DFEB04C-0E53-4430-B6F8-ED887E78EA9E"; }elseif ($type == 4){ // 存货 $code = "PROC-9934D26D-D25D-408B-8B0E-FBD88EAB510D"; }elseif ($type == 5){ // 供应商 $code = "PROC-30C00FA9-BD09-4139-92AD-220579109E07"; } }elseif ($login_type == DDEmployee::type_two){ //杭州 if($type == 1){ // 采购单 $code = "PROC-DC4D5B5E-EF49-4230-A0A8-E6CCA55336DC"; }elseif ($type == 2){ // 请购单 $code = "PROC-E44BE6B5-4530-42E1-A1A1-707708E45841"; }elseif ($type == 3){ // 采购入库单 $code = "PROC-E166769C-4FEA-4D49-BD3C-F9183BD366F2"; }elseif ($type == 4){ // 存货 $code = "PROC-229F1263-4180-4B50-A92B-749E699AB16E"; }elseif ($type == 5){ // 供应商 $code = "PROC-D7304810-1767-4FA3-A62C-E791B5801715"; } } return $code ?? ""; } private function getFormData($data, $user){ //cs // $formData = [ [ "name" => "订单日期", "value" => "2025-09-23" ], [ "name" => "订单编号", "value" => "PO20250923001" ], [ "name" => "业务类型", "value" => "标准采购" ], [ "name" => "供应商", "value" => "XX供应商有限公司" ], [ "name" => "制单人", "value" => "陈庆鹏" ], [ "name" => "表体", "value" => json_encode([ [ [ "name" => "存货名称", "value" => "打印机" ], [ "name" => "数量", "value" => "2" ], [ "name" => "主计量单位", "value" => "台" ], [ "name" => "原币价税合计", "value" => "3000" ] ], [ [ "name" => "存货名称", "value" => "显示器" ], [ "name" => "数量", "value" => "5" ], [ "name" => "主计量单位", "value" => "个" ], [ "name" => "原币价税合计", "value" => "5000" ] ] ], JSON_UNESCAPED_UNICODE) ] ]; // return [true, $formData]; //cs $service = new U8ServerService($user); $error = $service->getError(); if(! empty($error)) return [false, $error]; [$success, $order] = $service->getOrderDetails($data, $user); if(! $success) return [false, $order]; $type = $data['type']; if($type == 1){ // 采购单 $formData = $this->typeOne($order); }elseif ($type == 2){ // 采购请购单 $formData = $this->typeTwo($order); }elseif($type == 3){ // 采购入库单 $formData = $this->typeThree($order); }elseif($type == 4){ // 存货 $formData = $this->typeFour($order); }elseif($type == 5){ // 供应商 $formData = $this->typeFive($order); } if(empty($formData)) return [false, '审批参数不能为空']; return [true, $formData]; } private function typeOne($userOrder){ if (empty($userOrder)) return []; $formData = [ [ "name" => "订单日期", "value" => date('Y-m-d', strtotime($userOrder['order_date'] ?? '')) ], [ "name" => "订单编号", "value" => $userOrder['order_number'] ?? '' ], [ "name" => "业务类型", "value" => $userOrder['business_type'] ?? '' ], [ "name" => "供应商", "value" => $userOrder['supplier_title'] ?? '' ], [ "name" => "制单人", "value" => $userOrder['crt_name'] ?? '' ], [ "name" => "表体", // 对应 TableField 的 label "value" => json_encode( array_map(function($item){ return [ [ "name" => "存货名称", "value" => $item['product_title'] ?? '' ], [ "name" => "数量", "value" => $item['quantity'] ?? 0 ], [ "name" => "主计量", // 修改这里,对应模板字段 "value" => $item['unit_title'] ?? '' ], [ "name" => "原币价税合计", "value" => $item['amount'] ?? 0 ] ]; }, $userOrder['detail'] ?? []), JSON_UNESCAPED_UNICODE ) ] ]; return $formData; } private function typeTwo($userOrder){ if (empty($userOrder)) return []; $formData = [ [ "name" => "单据号", "value" => $userOrder['order_number'] ?? '' ], [ "name" => "日期", "value" => date('Y-m-d', strtotime($userOrder['order_date'] ?? '')) ], [ "name" => "业务类型", "value" => $userOrder['business_type'] ?? '' ], [ "name" => "请购人", "value" => $userOrder['purchase_name'] ?? '' ], [ "name" => "制单人", "value" => $userOrder['crt_name'] ?? '' ], [ "name" => "表体", // 对应 TableField 的 label "value" => json_encode( array_map(function($item){ return [ [ "name" => "存货名称", "value" => $item['product_title'] ?? '' ], [ "name" => "数量", "value" => $item['quantity'] ?? 0 ], [ "name" => "主计量", // 修改这里,对应模板字段 "value" => $item['unit_title'] ?? '' ], [ "name" => "要求到货日期", "value" => $item['need_arrived_date'] ?? '' ] ]; }, $userOrder['detail'] ?? []), JSON_UNESCAPED_UNICODE ) ] ]; return $formData; } private function typeThree($userOrder){ if (empty($userOrder)) return []; $formData = [ [ "name" => "入库单号", "value" => $userOrder['order_number'] ?? '' ], [ "name" => "入库日期", "value" => date('Y-m-d', strtotime($userOrder['order_date'] ?? '')) ], [ "name" => "仓库", "value" => $userOrder['warehouse_name'] ?? '' ], [ "name" => "入库类别", "value" => $userOrder['rd_style_name'] ?? '' ], [ "name" => "供货单位", "value" => $userOrder['supplier_title'] ?? '' ], [ "name" => "制单人", "value" => $userOrder['crt_name'] ?? '' ], [ "name" => "表体", // 对应 TableField 的 label "value" => json_encode( array_map(function($item){ return [ [ "name" => "存货名称", "value" => $item['product_title'] ?? '' ], [ "name" => "数量", "value" => $item['quantity'] ?? 0, ], [ "name" => "主计量", // 修改这里,对应模板字段 "value" => $item['unit_title'] ?? '' ], [ "name" => "原币价税合计", "value" => $item['tax_amount'] ?? 0 ] ]; }, $userOrder['detail'] ?? []), JSON_UNESCAPED_UNICODE ) ] ]; return $formData; } private function typeFour($userOrder){ if (empty($userOrder)) return []; $formData = [ [ "name" => "存货编码", "value" => $userOrder['code'] ?? '' ], [ "name" => "存货名称", "value" => $userOrder['title'] ?? '' ], [ "name" => "规格型号", "value" => $userOrder['size'] ?? '' ], [ "name" => "计量单位组名", "value" => $userOrder['unit_group_code_title'] ?? '' ], [ "name" => "主计量单位名", "value" => $userOrder['unit_code_title'] ?? '' ], [ "name" => "生产企业", "value" => $userOrder['vendor_code_title'] ?? '' ], [ "name" => "制单人", "value" => $userOrder['crt_name'] ?? '' ], ]; return $formData; } private function typeFive($userOrder){ if (empty($userOrder)) return []; $formData = [ [ "name" => "供应商编码", "value" => $userOrder['code'] ?? '' ], [ "name" => "供应商名称", "value" => $userOrder['title'] ?? '' ], [ "name" => "供应商简称", "value" => $userOrder['easy_title'] ?? '' ], [ "name" => "制单人", "value" => $userOrder['crt_name'] ?? '' ], ]; return $formData; } public function getTemplateFields($data) { $processCode = $data['code'] ?? ""; if (empty($processCode)) { return [false, '模板编号 process_code 不能为空']; } [$ok, $tokenData] = $this->getAccessToken(); if (! $ok) return [false, $tokenData]; $accessToken = $tokenData['access_token']; // 注意这里是 GET,并且 processCode 是 query 参数 $url = "https://api.dingtalk.com/v1.0/workflow/forms/schemas/processCodes?processCode={$processCode}"; $resp = $this->curlOpen1($url, [ 'request' => 'get', 'header' => [ "Content-Type: application/json", "x-acs-dingtalk-access-token: {$accessToken}" ], ]); $res = json_decode($resp, true); if (isset($res['schemas'])) { return [true, $res['schemas']]; } else { return [false, $res]; } } protected function curlOpen1($url, $config = []) { $default = [ 'post' => false, 'request' => 'get', 'header' => [], 'json' => null, 'timeout' => 30 ]; $arr = array_merge($default, $config); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, $arr['timeout']); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); if (!empty($arr['header'])) { curl_setopt($ch, CURLOPT_HTTPHEADER, $arr['header']); } if ($arr['post'] || $arr['request'] !== 'get') { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($arr['request'])); if ($arr['json'] !== null) { curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arr['json'], JSON_UNESCAPED_UNICODE)); } } $result = curl_exec($ch); if ($result === false) { $err = curl_error($ch); curl_close($ch); return json_encode(['error' => $err]); } curl_close($ch); return $result; } }