diff --git a/api/controllers/Welcome.php b/api/controllers/Welcome.php index 1af29068..c3c233e6 100644 --- a/api/controllers/Welcome.php +++ b/api/controllers/Welcome.php @@ -13,11 +13,35 @@ class Welcome extends CI_Controller public function test() { -// require_once COMMPATH . 'third_party/SmsEmms/Sms.php'; -// $sms = new Sms(); -// $sms = new ThirdParty\SmsEmms\Sms(); -// $req = $sms->send('13860199646', '您的验证码为:123456,请勿泄露于他人!'); -// print_r($req); +// $this->load->library('carHome/daiFu'); +// $daiFu = new DaiFu(); +// $daiFu->uploadIdCardImage(); +// $idCard = "350802199111298215"; +// $req = $daiFu->queryIdCardImage($idCard); +// $requestId = time(); +// $realName = "林聪聪"; +// $cellphone = "18350451617"; +// $req = $daiFu->signUp($requestId, $idCard, $realName, $cellphone); +// $req = $daiFu->querySignUp($requestId, $idCard, $realName, $cellphone); +// var_dump($req->isSuccess()); +// var_dump($req->getMessage()); +// var_dump($req->getData()); +// $this->load->library('carHome/callOut'); +// $this->load->library('carHome/callOutWechat'); +// $callOut = new CallOut(); +// $callOutWechat = new CallOutWechat(); +// $req = $callOutWechat->getToken(); +// $orderId = $requestId = time(); +// $agentPhoneNo = '18350451617'; +// $customerPhoneNo = '13365081602'; +// $req = $callOutWechat->bind($requestId, $orderId, $agentPhoneNo, $customerPhoneNo); +// $req = $callOutWechat->outBind($requestId, $orderId, $agentPhoneNo, $customerPhoneNo); +// var_dump($req); +// $recKeyStr = "ZX202508211605082100201400636"; +// $req = $callOutWechat->getAudio($recKeyStr); +// var_dump($req->getData()); +// var_dump($req->getData()); +// $callOut->call(); // $this->load->model('receiver/receiver_customers_model', 'customers_model'); // $rid = 17418; // $bizId = 57; diff --git a/api/controllers/plan/CallBack.php b/api/controllers/plan/CallBack.php new file mode 100644 index 00000000..318a0965 --- /dev/null +++ b/api/controllers/plan/CallBack.php @@ -0,0 +1,209 @@ +load->model('receiver/receiver_call_model', 'callModel'); + $this->load->model('receiver/receiver_call_wechat_model', 'callWechat'); + $this->load->model('receiver/receiver_customers_model', 'customers_model'); + $this->load->model('app/licheb/app_licheb_users_model', 'app_user_model'); + $this->load->model('receiver/receiver_customer_oplogs_model'); + $this->load->model('sys/sys_admin_model'); + $this->load->library('carHome/callOutWechat'); + $this->load->library('qiniu'); + } + + /** + * 好车补推送回调 + * @return void + */ + public function index() + { + $logPath = "callBack.log"; + //接收json 数据 + $post = $this->input->post(); + debug_log("post: " . json_encode($post, JSON_UNESCAPED_UNICODE), $logPath, $this->logDir); + $json = file_get_contents('php://input'); + debug_log("json: " . $json, $logPath, $this->logDir); + $data = $json ? json_decode($json, true) : []; + try { + //处理业务逻辑 + if (!$data || !$data['requestId']) { + throw new Exception('参数错误'); + } + $row = $this->callModel->get(['reqId' => $data['requestId']]); + if (!$row) { + throw new Exception('拨号记录不存在'); + } + $callData = $data['calldata']; + $upData = [ + 'orderId' => $callData['orderId'] ?: '', + 'sessionId' => $callData['sessionId'] ?: '', + 'agentId' => $callData['agentId'] ?: '', + 'agentUm' => $callData['agentUm'] ?: '', + 'agentPhoneNo' => $callData['agentPhoneNo'] ?: '', + 'customerPhoneNo' => $callData['customerPhoneNo'] ?: '', + 'agentDispNo' => $callData['agentDispNo'] ?: '', + 'customerDispNo' => $callData['customerDispNo'] ?: '', + 'voiceId' => $callData['voiceId'] ?: '', + 'finishType' => $callData['finishType'], + 'callType' => $callData['callType'], + 'hangupType' => $callData['hangupType'], + 'status' => Receiver_call_wechat_model::STATUS_FINISH, + 'apiResult' => $json + ]; + $this->callModel->update($upData, ['id' => $row['id']]); + } catch (Exception $e) { + debug_log("错误信息: " . $e->getMessage(), $logPath, $this->logDir); + } + $data = ['code' => 200, 'msg' => '成功', 'data' => []]; + $this->output + ->set_content_type('application/json') + ->set_output(json_encode($data, JSON_UNESCAPED_UNICODE)); + } + + /** + * 拨打电话回调(sadmin后台和小程序) + * @return void + */ + public function app() + { + $logPath = "callBackApp.log"; + //接收json 数据 + $post = $this->input->post(); + debug_log("post: " . json_encode($post, JSON_UNESCAPED_UNICODE), $logPath, $this->logDir); + $json = file_get_contents('php://input'); + debug_log("json: " . $json, $logPath, $this->logDir); + $data = $json ? json_decode($json, true) : []; + try { + //处理业务逻辑 + if (!$data || !$data['requestId']) { + throw new Exception('参数错误'); + } + $row = $this->callWechat->get(['reqId' => $data['requestId']]); + if (!$row) { + throw new Exception('拨号记录不存在'); + } + $callData = $data['calldata']; + $upData = [ + 'orderId' => $callData['orderId'] ?: '', + 'sessionId' => $callData['sessionId'] ?: '', + 'agentId' => $callData['agentId'] ?: '', + 'agentPhoneNo' => $callData['agentPhoneNo'] ?: '', + 'customerPhoneNo' => $callData['customerPhoneNo'] ?: '', + 'agentDispNo' => $callData['agentDispNo'] ?: '', + 'customerDispNo' => $callData['customerDispNo'] ?: '', + 'voiceId' => $callData['voiceId'] ?: '', + 'finishType' => $callData['finishType'], + 'callType' => $callData['callType'], + 'hangupType' => $callData['hangupType'], + 'recordpath' => $callData['recordpath'] ?: '', + 'status' => Receiver_call_wechat_model::STATUS_FINISH, + 'apiResult' => $json + ]; + $callData['agentRingTime'] && $upData['agentRingTime'] = $callData['agentRingTime']; + $callData['agentAnswerTime'] && $upData['agentAnswerTime'] = $callData['agentAnswerTime']; + $callData['userRingTime'] && $upData['userRingTime'] = $callData['userRingTime']; + $callData['userAnswerTime'] && $upData['userAnswerTime'] = $callData['userAnswerTime']; + $callData['endTime'] && $upData['endTime'] = $callData['endTime']; + if ($callData['endTime'] && $callData['agentAnswerTime']) { + $upData['telDuration'] = strtotime($callData['endTime']) - strtotime($callData['agentAnswerTime']); + } + if ($callData['endTime'] && $callData['userAnswerTime']) { + $upData['telDuration'] = strtotime($callData['endTime']) - strtotime($callData['userAnswerTime']); + } + $this->callWechat->update($upData, ['id' => $row['id']]); + if ($row['cfId'] && $row['cfPlatform'] == Receiver_call_wechat_model::CF_PLATFORM_WX_APP) { //理车宝 + $user = $this->app_user_model->get(['id' => $row['cfUid']]); + $cust = $this->customers_model->get(['id' => $row['cfId']]); + $this->load->library('receiver/customers_entity'); + $visit = 1; + $this->customers_entity->add_log_visit($cust['id'], $row['cfUid'], $user['uname'], $row['id'], 2, $visit, [], 'wxapp', Receiver_customer_oplogs_model::SUB_TYPE_AUTO_CALL_OUT_WECHAT); + } elseif ($row['cfId'] && $row['cfPlatform'] == Receiver_call_wechat_model::CF_PLATFORM_ADMIN) { //后台 + $admin_id = $row['cfUid']; + $admin = $this->sys_admin_model->get(['id' => $admin_id]); + $addData = array( + 'uid' => $admin_id, + 'uname' => $admin['username'] ? $admin['username'] : '', + 'type' => 2,//类型 0 普通 1短信 2电话 + 'sub_type' => Receiver_customer_oplogs_model::SUB_TYPE_AUTO_CALL_OUT_WECHAT, + 'log' => $row['id'], + 'c_time' => time() + ); + if ($row['cfType'] == Receiver_call_wechat_model::CF_TYPE_CLUE) {//线索拨打电话回调 + $this->load->model('receiver/receiver_clue_oplogs_model', 'mdOplogs'); + $addData['clue_id'] = $row['cfId']; + } else if ($row['cfType'] == Receiver_call_wechat_model::CF_TYPE_CUSTOMERS) {//客户拨打电话回调 + $this->load->model('receiver/receiver_customer_oplogs_model', 'mdOplogs'); + $addData['customer_id'] = $row['cfId']; + $addData['cf_platform'] = Receiver_call_wechat_model::CF_PLATFORM_ADMIN; + } + $this->mdOplogs->add($addData); + } + } catch (Exception $e) { + debug_log("错误信息: " . $e->getMessage(), $logPath, $this->logDir); + } + $data = ['code' => 200, 'msg' => '成功', 'data' => []]; + $this->output + ->set_content_type('application/json') + ->set_output(json_encode($data, JSON_UNESCAPED_UNICODE)); + } + + // 下载录音文件 + public function downVideo() + { + $logPath = "downVideo.log"; + $where = array( + "recordUrl" => "", + "voiceId <> ''" => null + ); + $count = $this->callWechat->count($where); + $failed_num = $success_num = $do_num = 0; + if ($count) { + $rows = $this->callWechat->select($where, 'id asc', 1, 20, 'id,voiceId,reqId'); + $callOutWechat = new CallOutWechat(); + foreach ($rows as $key => $val) { + try { + debug_log("下载录音文件: " . $val['id'], $logPath, $this->logDir); + $req = $callOutWechat->getAudio($val['voiceId']); + if (!$req->getData()) { + throw new Exception('获取录音文件失败'); + } + $videoData = $req->getData(); + $qiniu = new Qiniu(['type' => 'video']); + $filename = $qiniu->getFileName($val['reqId'], 'mp3', 'call_out_wechat_video_'); + $q_res = $qiniu->save($filename, $videoData); + if (!$q_res || !$q_res['url']) { + throw new Exception('文件上传七牛失败'); + } + $recUrl = $q_res['url']; + $this->callWechat->update(['recordUrl' => $recUrl], ['id' => $val['id']]); + debug_log("录音文件保存成功: " . $recUrl, $logPath, $this->logDir); + $success_num++; + } catch (Exception $e) { + debug_log("错误信息: " . $e->getMessage(), $logPath, $this->logDir); + $failed_num++; + } + $do_num++; + } + } + echo "do_num:{$do_num},success_num:{$success_num},failed_num:{$failed_num}"; + } + + public function test() + { + $logPath = "test.log"; + debug_log("server: " . json_encode($_SERVER, JSON_UNESCAPED_UNICODE), $logPath, $this->logDir); + $post = $this->input->post(); + debug_log("post: " . json_encode($post, JSON_UNESCAPED_UNICODE), $logPath, $this->logDir); + echo '333'; + } +} \ No newline at end of file diff --git a/common/libraries/carHome/DaiFu.php b/common/libraries/carHome/DaiFu.php new file mode 100644 index 00000000..fbbb5925 --- /dev/null +++ b/common/libraries/carHome/DaiFu.php @@ -0,0 +1,254 @@ +ci = &get_instance(); + if (!is_product()) { //测试环境 + $this->baseUrl = 'https://app-uat.zkzs6.com/api/v1'; +// $this->baseUrl = 'https://api.ss.haodian.cn/plan/callBack/test'; + $this->clientKey = "808641732177002496"; + $this->privateKey = "5d8fd442a18da9ae3f39916d6504127k"; + $this->agentParentId = "655342131023806464"; + } + $this->ci->load->library('myResponse'); + } + + /** + * 公共参数 + * @param $method + * @return array + */ + public function getCommonData($method) + { + $formData = [ + "name" => $method, + "client_key" => $this->clientKey, + "timestamp" => $this->getNowTime(), + ]; + return $formData; + } + + /** + * 证件上传 + * @return MyResponse + */ + public function uploadIdCardImage() + { + try { + $baseData = $this->getCommonData(self::UPLOAD_ID_CARD_IMAGE); + $imgUrl = "https://img.liche.cn/liche/2025/09/b6ef0ca29d6f1485/4d49f2821472034e.png"; + $frontImage = $this->urlToBase64($imgUrl); + $data = [ + 'request_id' => time(), + 'id_card' => '350802199111298215', + 'real_name' => '林聪聪', + 'cellphone' => '18350451617', + 'upload_way' => 'DIRECT', //求方式:DIRECT(直接上传),目前仅支持 DIRECT + 'front_image' => $frontImage, + 'back_image' => $frontImage, + ]; + $baseData['data'] = $data; + $reqData = [ + 'req' => json_encode($baseData, JSON_UNESCAPED_UNICODE) + ]; + $reqData['sign'] = $this->sign($reqData['req']); + list($responseContent, $statusCode) = $this->httpRequestPost($this->baseUrl, $reqData); + if ($statusCode != 200) { + throw new Exception("请求失败"); + } + $responseData = json_decode($responseContent, true); + if ($responseData['code']) { + throw new Exception($responseData['message']); + } + return new MyResponse(EXIT_SUCCESS, '提交成功', $responseData['data']); + } catch (Exception $e) { + return new MyResponse(EXIT_ERROR, $e->getMessage()); + } + } + + /** + * @param $idCard + * @return MyResponse + */ + public function queryIdCardImage($idCard) + { + try { + $baseData = $this->getCommonData(self::QUERY_ID_CARD_IMAGE); + $data = [ + 'request_id' => time(), + 'id_card' => $idCard + ]; + $baseData['data'] = $data; + $reqData = [ + 'req' => json_encode($baseData, JSON_UNESCAPED_UNICODE) + ]; + $reqData['sign'] = $this->sign($reqData['req']); + list($responseContent, $statusCode) = $this->httpRequestPost($this->baseUrl, $reqData); + if ($statusCode != 200) { + throw new Exception("请求失败"); + } + $responseData = json_decode($responseContent, true); + if ($responseData['code']) { + throw new Exception($responseData['message']); + } + return new MyResponse(EXIT_SUCCESS, '提交成功', $responseData['data']); + } catch (Exception $e) { + return new MyResponse(EXIT_ERROR, $e->getMessage()); + } + } + + /** + * 签约 + * @param $requestId + * @param $idCard + * @param $realName + * @param $cellphone + * @return MyResponse + */ + public function signUp($requestId, $idCard, $realName, $cellphone) + { + try { + $baseData = $this->getCommonData(self::SIGN_UP); + $data = [ + 'request_id' => $requestId, + 'id_card' => $idCard, + 'real_name' => $realName, + 'cellphone' => $cellphone, + 'agent_parent_id' => $this->agentParentId + ]; + $baseData['data'] = $data; + $reqData = [ + 'req' => json_encode($baseData, JSON_UNESCAPED_UNICODE) + ]; + $reqData['sign'] = $this->sign($reqData['req']); + list($responseContent, $statusCode) = $this->httpRequestPost($this->baseUrl, $reqData); + if ($statusCode != 200) { + throw new Exception("请求失败"); + } + $responseData = json_decode($responseContent, true); + if ($responseData['code']) { + throw new Exception($responseData['message']); + } + return new MyResponse(EXIT_SUCCESS, '提交成功', $responseData['data']); + } catch (Exception $e) { + return new MyResponse(EXIT_ERROR, $e->getMessage()); + } + } + + public function querySignUp($requestId, $idCard, $realName, $cellphone) + { + try { + $baseData = $this->getCommonData(self::QUERY_SIGN_UP); + $data = [ + 'request_id' => $requestId, + 'id_card' => $idCard, + 'real_name' => $realName, + 'cellphone' => $cellphone, + 'agent_parent_id' => $this->agentParentId + ]; + $baseData['data'] = $data; + $reqData = [ + 'req' => json_encode($baseData, JSON_UNESCAPED_UNICODE) + ]; + $reqData['sign'] = $this->sign($reqData['req']); + list($responseContent, $statusCode) = $this->httpRequestPost($this->baseUrl, $reqData); + if ($statusCode != 200) { + throw new Exception("请求失败"); + } + $responseData = json_decode($responseContent, true); + if ($responseData['code']) { + throw new Exception($responseData['message']); + } + return new MyResponse(EXIT_SUCCESS, '提交成功', $responseData['data']); + } catch (Exception $e) { + return new MyResponse(EXIT_ERROR, $e->getMessage()); + } + } + + private function httpRequestPost($url, $formData = []) + { + $logPath = "httpRequestPost.log"; + try { + $client = new Client(); + debug_log("请求地址: {$url}", $logPath, $this->logDir); + debug_log("请求参数:" . json_encode($formData, JSON_UNESCAPED_UNICODE), $logPath, $this->logDir); + $response = $client->post($url, [ + 'headers' => [ + 'Content-Type' => 'application/x-www-form-urlencoded', + ], + 'form_params' => $formData + ]); + $responseContent = $response->getBody()->getContents(); + debug_log("返回结果:" . $responseContent, $logPath, $this->logDir); + return [$responseContent, $response->getStatusCode()]; + } catch (RequestException $e) { + debug_log("", $logPath, $this->logDir); + return [$e->getMessage(), 0]; + } + } + + /** + * 生成HMAC签名 + * @param string $data 待签名的数据 + * @return string Base64编码的签名结果 + * @throws Exception 当算法不支持时抛出异常 + */ + function sign($data) + { + // 计算HMAC哈希值(二进制格式) + $hmac = hash_hmac('sha256', $data, $this->privateKey, true); + // 转换为Base64编码并返回 + return base64_encode($hmac); + } + + private function getNowTime() + { + $currentTime = new DateTime(); + $formattedCurrent = $currentTime->format('Y-m-d\TH:i:s.u'); + return substr($formattedCurrent, 0, 23); + } + + /** + * 简化版:网络图片URL转Base64编码 + * @param string $url 图片URL + * @return string|false 转换结果 + */ + public function urlToBase64($url) + { + // 设置超时时间 + $context = stream_context_create([ + 'http' => ['timeout' => 10], + 'ssl' => ['verify_peer' => false] // 跳过SSL验证 + ]); + + // 获取图片内容 + $imageData = @file_get_contents($url, false, $context); + if (!$imageData) return false; + + // 获取MIME类型 + $finfo = new finfo(FILEINFO_MIME_TYPE); + $mime = $finfo->buffer($imageData); + + // 生成Base64字符串 + return 'data:' . $mime . ';base64,' . base64_encode($imageData); + } +} \ No newline at end of file