Files
charge-pile-serve/app/controller/TeldTest.php
MeSHard 94f7e83679 init
2025-11-10 16:12:07 +08:00

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);
}
}