372 lines
13 KiB
PHP
372 lines
13 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare (strict_types=1);
|
||
|
|
|
||
|
|
namespace app\controller;
|
||
|
|
|
||
|
|
|
||
|
|
use app\controller\Bus\PlugCharge;
|
||
|
|
use app\model\EnterpriseUser;
|
||
|
|
use app\model\ServiceFee;
|
||
|
|
use DateInterval;
|
||
|
|
use DateTime;
|
||
|
|
use Overtrue\Pinyin\Pinyin;
|
||
|
|
use think\facade\Cache;
|
||
|
|
use think\facade\Db;
|
||
|
|
use think\Request;
|
||
|
|
|
||
|
|
|
||
|
|
class TeldTest
|
||
|
|
{
|
||
|
|
|
||
|
|
public $OperatorID = 'MACFHBM3X'; //运营商标识
|
||
|
|
public $OperatorSecret = '1234567890abcdef';//运营商密钥
|
||
|
|
public $DataSecret = '1234567890abcdef';//消息秘钥
|
||
|
|
public $DataSecretIV = '1234567890abcdef';//消息密钥初始化向量
|
||
|
|
public $SigSecret = '1234567890abcdef';//签名密钥
|
||
|
|
public $Seq = '001';
|
||
|
|
public $url = 'http://hlht.teld9.xyz/evcs/v20191230/';//测试地址
|
||
|
|
public $connectorID = '3702121094205';//桩子号
|
||
|
|
public $EquipAuthSeq = '3702121094205';//桩子认证号
|
||
|
|
|
||
|
|
public $iv = '1234567890abcdef';//iv的长度要根据加密方式和模式来定,aes-128-cbc偏移量的是16位
|
||
|
|
|
||
|
|
public $key = '1234567890abcdef';
|
||
|
|
//获取token
|
||
|
|
//查询充电站信息
|
||
|
|
//设备接口状态查询
|
||
|
|
//设备状态变化推送
|
||
|
|
//查询业务策略信息
|
||
|
|
//请求设备认证
|
||
|
|
//请求启动充电
|
||
|
|
//推送启动充电结果
|
||
|
|
//查询充电状态
|
||
|
|
//推送充电状态
|
||
|
|
//请求停止充电
|
||
|
|
//推送停止充电结果
|
||
|
|
//推送充电订单信息
|
||
|
|
//自助备案车牌号
|
||
|
|
//获取商户企业账户余额
|
||
|
|
//订单文件下载
|
||
|
|
|
||
|
|
//token
|
||
|
|
public function getToken()
|
||
|
|
{
|
||
|
|
$OperatorID = $this->OperatorID;
|
||
|
|
$OperatorSecret = $this->OperatorSecret;
|
||
|
|
$time = date('YmdHis');
|
||
|
|
$Seq = $this->Seq;
|
||
|
|
$mess = array('OperatorID' => $OperatorID, 'OperatorSecret' => $OperatorSecret);
|
||
|
|
$data = json_encode($mess);
|
||
|
|
|
||
|
|
|
||
|
|
$en_data = $this->encrypt($data);
|
||
|
|
|
||
|
|
$de_Sig = $OperatorID . $en_data . $time . $Seq;
|
||
|
|
|
||
|
|
$Sig = $this->HMAC($de_Sig, $this->DataSecret);
|
||
|
|
$kk['OperatorID'] = $OperatorID;
|
||
|
|
$kk['Data'] = $en_data;
|
||
|
|
$kk['TimeStamp'] = $time;
|
||
|
|
$kk['Seq'] = $Seq;
|
||
|
|
$kk['Sig'] = $Sig;
|
||
|
|
|
||
|
|
|
||
|
|
$datas = $this->CurlSend_Token($this->url . '/query_token', $kk);
|
||
|
|
|
||
|
|
$array_data = (array)$datas;
|
||
|
|
if ($array_data['Ret'] == 0) {
|
||
|
|
$token = $array_data['Data'];
|
||
|
|
$de_data = $this->decrypt($token);
|
||
|
|
$arr_token = json_decode($de_data);
|
||
|
|
$array_token = (array)$arr_token;
|
||
|
|
$token = $array_token['AccessToken'];
|
||
|
|
Cache::set('token', $token, 7200);
|
||
|
|
return $token;
|
||
|
|
} else {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//设备认证
|
||
|
|
public function queryEquipAuth()
|
||
|
|
{
|
||
|
|
Cache::delete('token');
|
||
|
|
$token = Cache::get('token');
|
||
|
|
if (!$token) {
|
||
|
|
$token = $this->getToken();
|
||
|
|
}
|
||
|
|
$datetime = date('YmdHis');
|
||
|
|
$kk['EquipAuthSeq'] = $this->EquipAuthSeq;
|
||
|
|
$kk['ConnectorID'] = $this->connectorID;
|
||
|
|
$en = $this->encrypt(json_encode($kk));
|
||
|
|
$sig = $this->OperatorID . $en . $datetime . $this->Seq;
|
||
|
|
$s = $this->HMAC($sig, $this->DataSecret);
|
||
|
|
$rr['OperatorID'] = $this->OperatorID;
|
||
|
|
$rr['Data'] = $en;
|
||
|
|
$rr['TimeStamp'] = $datetime;
|
||
|
|
$rr['Seq'] = $this->Seq;
|
||
|
|
$rr['Sig'] = $s;
|
||
|
|
$data = $rr;
|
||
|
|
$message = $this->CurlSend_Token($this->url . '/query_equip_auth', $data, $token);
|
||
|
|
|
||
|
|
$en_mess = $message['Data'];
|
||
|
|
$de_data = $this->decrypt($en_mess);
|
||
|
|
|
||
|
|
$arr = json_decode($de_data, true);
|
||
|
|
|
||
|
|
// Array
|
||
|
|
// (
|
||
|
|
// [FailReason] => 0
|
||
|
|
// [SuccStat] => 0
|
||
|
|
// [EquipAuthSeq] => 3702121094205
|
||
|
|
// [ConnectorID] => 3702121094105
|
||
|
|
// )
|
||
|
|
return $arr;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//开始充电
|
||
|
|
public function queryStartCharge()
|
||
|
|
{
|
||
|
|
$token = Cache::get('token');
|
||
|
|
if (!$token) {
|
||
|
|
$token = $this->getToken();
|
||
|
|
}
|
||
|
|
$datetime = date('YmdHis');
|
||
|
|
$kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
|
||
|
|
$kk['ConnectorID'] = $this->connectorID;
|
||
|
|
$kk['QRCode'] = 'QRCode';
|
||
|
|
$kk['PhoneNum'] = ''; //13698689669 个人支付必传,格式确保正确
|
||
|
|
$kk['PlateNum'] = '';// 车牌号
|
||
|
|
$en = $this->encrypt(json_encode($kk));
|
||
|
|
|
||
|
|
|
||
|
|
$sig = $this->OperatorID . $en . $datetime . $this->Seq;
|
||
|
|
$s = $this->HMAC($sig, $this->DataSecret);
|
||
|
|
$rr['OperatorID'] = $this->OperatorID;
|
||
|
|
$rr['Data'] = $en;
|
||
|
|
$rr['TimeStamp'] = $datetime;
|
||
|
|
$rr['Seq'] = $this->Seq;
|
||
|
|
$rr['Sig'] = $s;
|
||
|
|
|
||
|
|
|
||
|
|
$message = $this->CurlSend_Token($this->url . '/query_start_charge', $rr, $token);
|
||
|
|
|
||
|
|
$en_mess = $message['Data'];
|
||
|
|
$de_data = $this->decrypt($en_mess);
|
||
|
|
$arr = json_decode($de_data);
|
||
|
|
$array = (array)$arr;
|
||
|
|
|
||
|
|
return $array;
|
||
|
|
|
||
|
|
// Array (
|
||
|
|
// [StartChargeSeq] => MACFHBM3X175705873925064035
|
||
|
|
// [SuccStat] => 1
|
||
|
|
// [FailReason] => 18
|
||
|
|
// [StartChargeSeqStat] => 5
|
||
|
|
// [ConnectorID] => 3702121094105
|
||
|
|
// )
|
||
|
|
}
|
||
|
|
|
||
|
|
//充电状态
|
||
|
|
public function queryEquipChargeStatus()
|
||
|
|
{
|
||
|
|
$token = Cache::get('token');
|
||
|
|
if (!$token) {
|
||
|
|
$token = $this->getToken();
|
||
|
|
}
|
||
|
|
$datetime = date('YmdHis');
|
||
|
|
$kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
|
||
|
|
|
||
|
|
$en = $this->encrypt(json_encode($kk));
|
||
|
|
$sig = $this->OperatorID . $en . $datetime . $this->Seq;
|
||
|
|
|
||
|
|
$s = $this->HMAC($sig, $this->DataSecret);
|
||
|
|
|
||
|
|
$rr['OperatorID'] = $this->OperatorID;
|
||
|
|
$rr['Data'] = $en;
|
||
|
|
$rr['TimeStamp'] = $datetime;
|
||
|
|
$rr['Seq'] = $this->Seq;
|
||
|
|
$rr['Sig'] = $s;
|
||
|
|
$data = $rr;
|
||
|
|
$message = $this->CurlSend_Token($this->url . '/query_equip_charge_status ', $data, $token);
|
||
|
|
|
||
|
|
$en_mess = $message['Data'];
|
||
|
|
$de_data = $this->decrypt($en_mess);
|
||
|
|
$arr = json_decode($de_data);
|
||
|
|
$array = (array)$arr;
|
||
|
|
halt($array);
|
||
|
|
if (isset($array['TotalMoney'])) {
|
||
|
|
$area = \app\model\ChargeOrder::where('StartChargeSeq', $StartChargeSeq)->value('area');
|
||
|
|
$pinyin = new Pinyin();
|
||
|
|
$s = $pinyin->sentence($area);
|
||
|
|
$s = strtr($s, array(' ' => ''));
|
||
|
|
$table = 'charge_order_' . $s;
|
||
|
|
$table_user = 'user_' . $s;
|
||
|
|
$ll = array_diff_key($array, ["ChargeDetails" => 'xy', 'StartTime' => 'xy', "StartChargeSeq" => 'xy', 'ConnectorID' => 'xy', 'TotalMoney' => 'xy']);
|
||
|
|
$station_id = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('charge_station_id');
|
||
|
|
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
|
||
|
|
$openid = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('openid');
|
||
|
|
$detail_message = '';
|
||
|
|
if ((int)$station_type == 0) {
|
||
|
|
$ii = 1;
|
||
|
|
$total = 0;
|
||
|
|
$ElectMoney = 0;
|
||
|
|
$SeviceMoney = 0;
|
||
|
|
foreach ($array['ChargeDetails'] as $Details) {
|
||
|
|
$Details = (array)$Details;
|
||
|
|
$per_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid, $table_user)['Elect'];
|
||
|
|
$S_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid, $table_user)['Serve'];
|
||
|
|
$period_price = round($Details['DetailPower'] * $per_price, 2);
|
||
|
|
$service_price = round($Details['DetailPower'] * $S_price, 2);
|
||
|
|
$total_money = $period_price + $service_price;
|
||
|
|
$detail_message .= '时段' . $ii .
|
||
|
|
':开始时间:' . $Details['DetailStartTime'] . ',' .
|
||
|
|
'结束时间:' . $Details['DetailEndTime'] . ',' .
|
||
|
|
'所用度数:' . $Details['DetailPower'] . ',' .
|
||
|
|
'时段电费单价:' . $per_price . ',' .
|
||
|
|
'时段电费金额:' . $period_price . ',' .
|
||
|
|
'时段服务费单价:' . $S_price . ',' .
|
||
|
|
'时段服务费金额:' . $service_price . ',' .
|
||
|
|
'时段总价:' . $total_money . ';';
|
||
|
|
$ii += 1;
|
||
|
|
$total += $total_money;
|
||
|
|
$ElectMoney += $period_price;
|
||
|
|
$SeviceMoney += $service_price;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
$price = $this->GetPrice($station_id, $openid, $table_user);
|
||
|
|
$total = $ll['TotalPower'] * $price['EPrice'] + ($ll['TotalPower'] * $price['SPrice']);
|
||
|
|
$ElectMoney = $array['TotalPower'] * $price['EPrice'];
|
||
|
|
$SeviceMoney = $array['TotalPower'] * $price['SPrice'];
|
||
|
|
}
|
||
|
|
$ll['TotalMoney'] = round($total, 2);
|
||
|
|
$ll['ElecMoney'] = round($ElectMoney, 2);
|
||
|
|
$ll['SeviceMoney'] = round($SeviceMoney, 2);
|
||
|
|
$WithholdingMoney = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('WithholdingMoney');
|
||
|
|
$order_num = Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->value('order_number');
|
||
|
|
if ((float)$WithholdingMoney - (float)$ll['TotalMoney'] <= 3) {
|
||
|
|
$order = new ChargeOrder();
|
||
|
|
$order->EndOrder($openid, $order_num);
|
||
|
|
}
|
||
|
|
$ll['status'] = $ll['StartChargeSeqStat'];
|
||
|
|
$end_time = Db::table($table)->where('order_number', $order_num)->value('end_time');
|
||
|
|
$status = Db::table($table)->where('order_number', $order_num)->value('status');
|
||
|
|
if (empty($end_time) && $status != 4) {
|
||
|
|
Db::table($table)->where('StartChargeSeq', $StartChargeSeq)->save($ll);
|
||
|
|
}
|
||
|
|
return ['code' => 200];
|
||
|
|
} else {
|
||
|
|
return ['code' => 1];
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
//停止充电
|
||
|
|
public function queryStopCharge()
|
||
|
|
{
|
||
|
|
|
||
|
|
$token = Cache::get('token');
|
||
|
|
if (!$token) {
|
||
|
|
$token = $this->getToken();
|
||
|
|
}
|
||
|
|
$datetime = date('YmdHis');
|
||
|
|
$kk['StartChargeSeq'] = 'MACFHBM3X175705873925064035';
|
||
|
|
$kk['ConnectorID'] = $this->connectorID;
|
||
|
|
|
||
|
|
|
||
|
|
$en = $this->encrypt(json_encode($kk));
|
||
|
|
$sig = $this->connectorID . $en . $datetime . $this->Seq;
|
||
|
|
|
||
|
|
|
||
|
|
$s = $this->HMAC($sig, $this->DataSecret);
|
||
|
|
|
||
|
|
$rr['OperatorID'] = $this->connectorID;
|
||
|
|
$rr['Data'] = $en;
|
||
|
|
$rr['TimeStamp'] = $datetime;
|
||
|
|
$rr['Seq'] = $this->Seq;
|
||
|
|
$rr['Sig'] = $s;
|
||
|
|
|
||
|
|
$data = $rr;
|
||
|
|
$message = $this->CurlSend_Token($this->url . '/query_stop_charge', $data, $token);
|
||
|
|
|
||
|
|
halt($message);
|
||
|
|
$en_mess = $message['Data'];
|
||
|
|
$de_data = $this->decrypt($en_mess);
|
||
|
|
$arr = json_decode($de_data);
|
||
|
|
$array = (array)$arr;
|
||
|
|
return $array;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
public function index()
|
||
|
|
{
|
||
|
|
|
||
|
|
return print_r($this->queryStopCharge());
|
||
|
|
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
function CurlSend_Token($url, $data = '', $token = '')
|
||
|
|
{
|
||
|
|
$data = json_encode($data);
|
||
|
|
$ch = curl_init();
|
||
|
|
$headers = array();
|
||
|
|
if ($token) {
|
||
|
|
$headers[] = 'Authorization: Bearer ' . $token;
|
||
|
|
}
|
||
|
|
$headers[] = 'Content-Type: application/json;charset=utf-8';
|
||
|
|
$headers[] = 'Content-Length: ' . strlen($data);
|
||
|
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 对认证证书来源的检查
|
||
|
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
|
||
|
|
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||
|
|
curl_setopt($ch, CURLOPT_POST, 1);
|
||
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||
|
|
$curl_return = curl_exec($ch);
|
||
|
|
curl_close($ch);
|
||
|
|
return json_decode(trim($curl_return), true);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function HMAC($data, $key)
|
||
|
|
{
|
||
|
|
$key = $this->strToUtf8($key);
|
||
|
|
$data = $this->strToUtf8($data);
|
||
|
|
|
||
|
|
$b = 64; // byte length for md5
|
||
|
|
if (strlen($key) > $b) {
|
||
|
|
$key = pack("H32", md5($key));
|
||
|
|
}
|
||
|
|
$key = str_pad($key, $b, chr(0x00));
|
||
|
|
$ipad = str_pad('', $b, chr(0x36));
|
||
|
|
$opad = str_pad('', $b, chr(0x5c));
|
||
|
|
$k_ipad = $key ^ $ipad;
|
||
|
|
$k_opad = $key ^ $opad;
|
||
|
|
|
||
|
|
return strtoupper(md5($k_opad . pack("H32", md5($k_ipad . $data))));
|
||
|
|
}
|
||
|
|
|
||
|
|
function strToUtf8($str)
|
||
|
|
{
|
||
|
|
$encode = mb_detect_encoding($str, array("ASCII", 'UTF-8', "GB2312", "GBK", 'BIG5'));
|
||
|
|
if ($encode == 'UTF-8') {
|
||
|
|
return $str;
|
||
|
|
} else {
|
||
|
|
return mb_convert_encoding($str, 'UTF-8', $encode);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public function encrypt($input)
|
||
|
|
{
|
||
|
|
return base64_encode(openssl_encrypt($input, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv));
|
||
|
|
}
|
||
|
|
|
||
|
|
public function decrypt($input)
|
||
|
|
{
|
||
|
|
return openssl_decrypt(base64_decode($input), 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv);
|
||
|
|
}
|
||
|
|
}
|