平安外呼系统

This commit is contained in:
lcc
2025-08-15 13:58:48 +08:00
parent 77e8748d2c
commit 4651bae2ef
25 changed files with 1043 additions and 184 deletions
+128
View File
@@ -198,6 +198,134 @@ class CallBack extends CI_Controller
echo "do_num:{$do_num},success_num:{$success_num},failed_num:{$failed_num}";
}
/**
* 拨打电话回调(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";
+2
View File
@@ -43,6 +43,8 @@ class Plan extends CI_Controller
$plan[] = array('url' => base_url(array('plan', 'report', 'index')), 'interval' => 20); //门店日报
$plan[] = array('url' => base_url(array('plan', 'callBack', 'downVideo')), 'interval' => 1); //外呼下载录音文件
$this->plan = $plan;
}
+4 -10
View File
@@ -55,16 +55,10 @@ class Customerlogs extends Wxapp
}
if ($val['type'] == 2) {
$content = '拨打电话';
if ($val['sub_type'] == Receiver_customer_oplogs_model::SUB_TYPE_XZ) {
$rec_row = $this->receiver_xz_model->get(['id' => $val['log']], 'rec_url,duration');
$rec_row['rec_url'] && $record = $rec_row['rec_url'];
$rec_row['duration'] && $second = intval($rec_row['duration'] / 1000);
} else {
$rec_row = $this->receiver_yx_model->get(['id' => $val['log']], 'rec_url,duration');
$rec_row['rec_url'] && $record = get_yx_video($rec_row['rec_url']);
$rec_row['duration'] && $second = intval($rec_row['duration']);
}
!$rec_row['duration'] && $content .= '(未接通)';
list($rec_url, $rec_text, $duration) = $this->customer_oplogs_model->getRecordUrl($val['id']);
$rec_url && $record = $rec_url;
$duration && $second = intval($duration);
!$duration && $content .= '(未接通)';
}
$comments = [];
$res = $this->mdComments->select(['pid' => $val['id'], 'status' => 1, 'type' => 0], 'id asc', 0, 0
+73 -37
View File
@@ -23,13 +23,17 @@ class Xz extends Wxapp
$this->load->model('receiver/receiver_customers_model', 'customers_model');
$this->load->model('receiver/receiver_xz_model');
$this->load->library('carHome/callOutWechat');
$this->load->model('sys/sys_config_model', 'confModel');
$this->load->model('receiver/receiver_call_wechat_model', 'callWechat');
$this->log_file = 'call.log';
}
protected function get()
{
throw new Hd_Exception('系统调整,暂停服务', API_CODE_FAIL);
return;
//平安外呼
// throw new Hd_Exception('系统调整,暂停服务', API_CODE_FAIL);
// return;
$id = $this->input_param('id');
$type = intval($this->input_param('type'));
!$type && $type = 0;
@@ -47,42 +51,74 @@ class Xz extends Wxapp
if ($json && $json['hdy'] && $json['hdy']['tel']) {
$user_mobile = $json['hdy']['tel'];
}
$redis = &load_cache('redis');
$cache_key = "XZ_LICHEB_MOBILEA_{$user_mobile}_MOBILEB_{$customer_mobile}_{$admin_id}";
$call_mobile = $redis->get($cache_key);
if (!$call_mobile) {
$this->config->load('xcall');
$params = [
'app_id' => $this->config->item('app_id'),
'app_key' => $this->config->item('app_key'),
];
$seq_id = create_order_no();
$xcall = new Xcall($params);
$maxBindingTime = 10;//绑定时间
$result = $xcall->ABXbind($user_mobile, $customer_mobile, $seq_id, $maxBindingTime);
if (!$result['code']) { //绑定失败
debug_log("xz_failed_bind:customer_mobile【{$customer_mobile}", $this->log_file);
debug_log("xz_result:" . json_encode($result, JSON_UNESCAPED_UNICODE), $this->log_file);
throw new Hd_Exception($result['msg'], API_CODE_FAIL);
} else {
$this->data['middlenumber'] = $result['data']['virtualMobile'];
$add_data = [
'call_id' => $seq_id,
'display_number' => $result['data']['virtualMobile'],
'biz_id' => $row['biz_id'],
'cf_id' => $cus_id,
'cf_uid' => $admin_id,
'cf_title' => $cf_title,
'cf_platform' => 'api',
'json_data' => json_encode(['uname' => $session['uname']], JSON_UNESCAPED_UNICODE),
'c_time' => time()
];
$this->receiver_xz_model->add($add_data);
$call_mobile = $result['data']['virtualMobile'];
$redis->save($cache_key, $call_mobile, $maxBindingTime * 60);
}
//平安外呼
$cityId = $row['city_id'] ?: 350200;
$requestId = create_order_no($cityId, 'licheb');
//获取绑定配置信息
$configRow = $this->confModel->get(array('k' => Sys_config_model::CALL_CONFIG_KEY));
$jsonData = $configRow['v'] ? json_decode($configRow['v'], true) : [];
$callBackPhoneNo = $jsonData['callBackPhoneNo'] ?: '';
$callTime = $jsonData['callTime'] ?: 2;
$callbackTime = $jsonData['callbackTime'] ?: 60;
$callOutWechat = new CallOutWechat();
$req = $callOutWechat->bind($requestId, $row['cid'], $user_mobile, $customer_mobile, $callBackPhoneNo, $callTime, $callbackTime);
if (!$req->isSuccess()) {
throw new Hd_Exception($req->getMessage(), API_CODE_FAIL);
}
$data['mobile'] = $call_mobile;
$data['mobile'] = $req->getData()['x'];
if (!$data['mobile']) {
throw new Hd_Exception('获取虚拟号码失败', API_CODE_FAIL);
}
//添加记录
$add_data = [
'reqId' => $requestId,
'cfId' => $cus_id,
'cfUid' => $admin_id,
'cfType' => Receiver_call_wechat_model::CF_TYPE_CUSTOMERS,
'cfPlatform' => Receiver_call_wechat_model::CF_PLATFORM_WX_APP,
'createTime' => time()
];
$req = $this->callWechat->add($add_data);
if (!is_numeric($req)) {
throw new Hd_Exception('保存记录失败', API_CODE_FAIL);
}
return $data;
// $redis = &load_cache('redis');
// $cache_key = "XZ_LICHEB_MOBILEA_{$user_mobile}_MOBILEB_{$customer_mobile}_{$admin_id}";
// $call_mobile = $redis->get($cache_key);
// if (!$call_mobile) {
// $this->config->load('xcall');
// $params = [
// 'app_id' => $this->config->item('app_id'),
// 'app_key' => $this->config->item('app_key'),
// ];
// $seq_id = create_order_no();
// $xcall = new Xcall($params);
// $maxBindingTime = 10;//绑定时间
// $result = $xcall->ABXbind($user_mobile, $customer_mobile, $seq_id, $maxBindingTime);
// if (!$result['code']) { //绑定失败
// debug_log("xz_failed_bind:customer_mobile【{$customer_mobile}】", $this->log_file);
// debug_log("xz_result:" . json_encode($result, JSON_UNESCAPED_UNICODE), $this->log_file);
// throw new Hd_Exception($result['msg'], API_CODE_FAIL);
// } else {
// $this->data['middlenumber'] = $result['data']['virtualMobile'];
// $add_data = [
// 'call_id' => $seq_id,
// 'display_number' => $result['data']['virtualMobile'],
// 'biz_id' => $row['biz_id'],
// 'cf_id' => $cus_id,
// 'cf_uid' => $admin_id,
// 'cf_title' => $cf_title,
// 'cf_platform' => 'api',
// 'json_data' => json_encode(['uname' => $session['uname']], JSON_UNESCAPED_UNICODE),
// 'c_time' => time()
// ];
// $this->receiver_xz_model->add($add_data);
// $call_mobile = $result['data']['virtualMobile'];
// $redis->save($cache_key, $call_mobile, $maxBindingTime * 60);
// }
// }
// $data['mobile'] = $call_mobile;
return $data;
}