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

1223 lines
53 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\controller;
use app\common;
use app\model\EnterpriseUser;
use app\model\ServiceFee;
use app\Request;
use think\facade\Cache;
use think\facade\Db;
use think\facade\Log;
use think\response\Json;
/**
* 特来电对接
* https://ion.teld.cn/document
*/
class HardMessage extends common
{
/**
* 查询充电站信息query_stations_info
* @param $PageNo
* @return string
*/
public function Get_stations_info($PageNo = 1)
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk = [
'LastQueryTime' => '',
'PageNo' => $PageNo,
'PageSize' => 10,
];
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_stations_info', $data, $token);
$de_data = $this->Decrypt($message['Data']);
$array = json_decode($de_data, true);
// dd($array);
foreach ($array['StationInfos'] as $station_arr) {
$station_arr1 = (array)$station_arr;
$station_arr1 = array_diff_key($station_arr1, ["EquipmentInfos" => 'xy', "CtrlsInfos" => 'xy']);
$check = Db::table('stationinfo_slow')->where('StationID', $station_arr1['StationID'])->find();
if (!$check) {
Db::table('stationinfo_slow')->save($station_arr1);
}
foreach ($station_arr['EquipmentInfos'] as $equipment_arr) {
$equipment_arr1 = (array)$equipment_arr;
$equipment_arr1 = array_diff_key($equipment_arr1, ["ConnectorInfos" => 'xy']);
$equipment_arr1['StationID'] = $station_arr['StationID'];
$check = Db::table('equipmentinfo_slow')->where('EquipmentID', $equipment_arr1['EquipmentID'])->find();
if (!$check) {
Db::table('equipmentinfo_slow')->save($equipment_arr1);
}
foreach ($equipment_arr['ConnectorInfos'] as $connector_arr) {
$connector_arr = (array)$connector_arr;
$connector_arr['EquipmentID'] = $equipment_arr['EquipmentID'];
$check = Db::table('connectorinfo_slow')->where('ConnectorID', $connector_arr['ConnectorID'])->find();
if (!$check) {
Db::table('connectorinfo_slow')->save($connector_arr);
}
}
}
}
return 'OK';
}
public function query_token()
{
$TimeStamp = '';
$Seq = '';
$OperatorSecret = config('hard.OperatorSecret');
$params = file_get_contents('php://input');
Db::table('charge_logo')->save(['name' => 'query_token', 'mark' => $params]);
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$checkParams = $this->checkParams($params);
if ($checkParams != 2) {
return json(['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]]);
}
$checkSig = $this->checkSig($OperatorID, $params);
if ($checkSig == 1) {
$data = json_encode(['OperatorID' => $OperatorID, 'SuccStat' => 1, 'FailReason' => 4]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '签名错误', 'Ret' => 4001, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
$datas = json_decode($data, true);
if (isset($datas['OperatorID']) && isset($datas['OperatorSecret'])) {
if (($datas['OperatorID'] == $OperatorID) && ($datas['OperatorSecret'] == $OperatorSecret)) {
$AccessToken = $this->signToken();
Cache::set('accesstoken', $AccessToken, 7200);
$strr = ['OperatorID' => $OperatorID, 'SuccStat' => 0, 'AccessToken' => $AccessToken,
'TokenAvailableTime' => 7200, 'FailReason' => 0];
$data = json_encode($strr);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '', 'Ret' => 0, 'Data' => $data, 'Sig' => $s]);
}
$re = ['OperatorID' => $OperatorID, 'SuccStat' => 1, 'FailReason' => 5];
$data = json_encode($re);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => 'OperatorID,Data错误', 'Ret' => 4003, 'Data' => $data, 'Sig' => $s]);
}
}
/**
* 设备接口状态查询query_station_status
* 数组长度不超过50
* @param $stationid
* @return void
*/
public function Get_station_status($stationid = [])
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk['StationIDs'] = $stationid;
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_station_status', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->Decrypt($en_mess);
$array = json_decode($de_data, true);
foreach ($array['StationStatusInfos'] as $stationStatusInfo_arr) {
foreach ($stationStatusInfo_arr['ConnectorStatusInfos'] as $connectorStatusInfo_arr) {
$connectorStatusInfo_arr['StationID'] = $stationStatusInfo_arr['StationID'];
Db::table('charge_pile')
->where('ConnectorID', $connectorStatusInfo_arr['ConnectorID'])
->update(['status' => $connectorStatusInfo_arr['Status']]);
$check = Db::table('connectorstatusinfo_slow')
->where('ConnectorID', $connectorStatusInfo_arr['ConnectorID'])
->find();
if (!$check) {
Db::table('connectorstatusinfo_slow')->save($connectorStatusInfo_arr);
} else {
Db::table('connectorstatusinfo_slow')->where('ConnectorID', $connectorStatusInfo_arr['ConnectorID'])->update($connectorStatusInfo_arr);
}
}
}
}
/**
* 设备状态变化推送 notification_stationStatus
* @param Request $request
* @return void
* 充电设备接口编码 ConnectorID 充电设备接口编码,同一运营商内唯一 是 字符串 <=26字符
*
* 充电设备接口状态 Status 0离网 1空闲 2占用未充电 3占用充电中 4占用预约锁定 255故障 是 整型
*
* 车位状态 ParkStatus 0未知 10空闲 50占用 否 整型
*
* 地锁状态 LockStatus 0未知 10已解锁 50已上锁
*/
public function notification_station(Request $request)
{
Db::table('charge_logo')->save(['name' => '设备状态变化推送notification_station', 'mark' => '']);
$params = file_get_contents('php://input');
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$authorization = $request->header()['authorization'];//传递过来的token
$auths = explode(' ', trim($authorization));
$auth = $auths[count($auths) - 1];
$checkParams = $this->checkParams($params);
if ($checkParams != 2) {
return ['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]];
}
if (!$auth) {
return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加');
}
if ($this->checkToken_assess($auth) == 1 || $this->checkSig($params['OperatorID'], $params) == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '请检查签名或Token过期或者无效', 'Ret' => 4002, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
Db::table('charge_logo')->save(['name' => '设备状态变化推送notification_station', 'mark' => $data]);
$data = json_decode($data, true);
$da = $data['ConnectorStatusInfo'];
if (isset($da['ConnectorID']) && isset($da['Status'])) {
$ConnectorID = $da['ConnectorID'];
Db::table('charge_pile')->where('ConnectorID', $ConnectorID)
->save(['status' => $da['Status'], 'is_pushed' => 1]);
return $this->encodeData(['Status' => 0], $params, 0);
}
}
/**
* 请求设备认证
* @param $EquipAuthSeq string
* @param $ConnectorID string
* @return mixed
*
* 设备认证流水号 EquipAuthSeq 字符串 格式“运营商ID+唯一编号”27字符
*
* 充电设备接口编码 ConnectorID 字符串 电设备接口编码:格式“6位行政区编码4位电站编码3位终端编码”13位字符
*
* 操作结果 SuccStat 整型 0:成功; 1:失败 失败原因 FailReason 整型 0:无; 1:此设备尚未插枪; 2:设备检测失败: 399:自定义
*/
public function Get_query_equip_auth($EquipAuthSeq, $ConnectorID)
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk = [
'EquipAuthSeq' => $EquipAuthSeq,
'ConnectorID' => $ConnectorID,
];
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_equip_auth', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->Decrypt($en_mess);
return json_decode($de_data, true);
}
/**
* 请求启动充电
* @param $StartChargeSeq string 充电订单号:格式“运营商ID+唯一编号”27字符
* @param $ConnectorID string 充电设备接口编码:格式“6位行政区编码4位电站编码3位终端编码”13位字符
* @param $QRCode string 二维码其他信息
* @param $PhoneNum string 手机号 false 个人支付必传,格式确保正确
* @param $PlateNum string 车牌号 false 停车减免必传,格式确保正确
* @return array
* 设备认证流水号 EquipAuthSeq 字符串 式“运营商ID+唯一编号”27字符
*
* 充电设备接口编码 ConnectorID 字符串 参见《电动汽车充换电服务信息交换 第2部分公共信息交换规范》
*
* 操作结果 SuccStat 整型 0:成功; 1:失败 失败原因 FailReason 整型 0:无; 1:此设备尚未插枪; 2:设备检测失败: 399:自定义
*
*/
public function Get_query_start_charge($StartChargeSeq, $ConnectorID, $QRCode, $PhoneNum = '', $PlateNum = '')
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk = [
'StartChargeSeq' => $StartChargeSeq,
'ConnectorID' => $ConnectorID,
'QRCode' => $QRCode,
'PhoneNum' => $PhoneNum,
'PlateNum' => $PlateNum,
];
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_start_charge', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->Decrypt($en_mess);
return json_decode($de_data, true);
}
/**
* 请求启动充电
* @param $StartChargeSeq string 充电订单号
* @param $ConnectorID string 充电设备接口编码
* @param $QRCode string 二维码其他信息
* @param $ChargeModel string 未知作用
* @param $vin string 车辆VIN码
* @param $PhoneNum string 手机号
* @return array
*/
public function Get_query_start_charge_test($StartChargeSeq, $ConnectorID, $QRCode, $ChargeModel, $vin = '', $PhoneNum = ''): array
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk = [
'StartChargeSeq' => $StartChargeSeq,
'ConnectorID' => $ConnectorID,
'QRCode' => $QRCode,
'PhoneNum' => $PhoneNum,
'ChargeModel' => $ChargeModel,
'Vin' => $vin,
];
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_start_charge', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->Decrypt($en_mess);
return json_decode($de_data, true);
}
/**
* @@@@@@@---------推送充电结果----------@@@@@@@@@@@@
* 发起充电后,由特来电方推送启动充电结果,包括充电订单号、订单状态、充电设备接口编码、充电启动时间。
* @param Request $request
*充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符
*
* 充电订单状态 StartChargeSeqStat 是 整型 1启动中 2充电中 3停止中 :已结束 5未知
*
* 充电设备接口编码 ConnectorID 是 字符串 格式“6位行政区编码4位电站编码3位终端编码”13位字符
*
* 充电启动时间 StartTime 是 字符串 格式“yyyy-MM-dd HH:mm:ss”
*
* 验证码 IdentCode 否 字符串 特来电将该字段作为启动充电失败原因错误码
*
* @return Json
* 充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符
*
* 操作结果 SuccStat 是 整型 0:成功; 1:失败
*
* 失败原因 FailReason 是 整型 0:无; 1:接收失败;
*/
public function notification_start_charge_result(Request $request)
{
$params = file_get_contents('php://input');
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$authorization = $request->header()['authorization'];//传递过来的token
$auths = explode(' ', trim($authorization));
$auth = $auths[count($auths) - 1];
$checkParams = $this->checkParams($params);
if ($checkParams != 2) {
return json(['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]]);
}
if (!$auth) {
return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加');
}
if ($this->checkToken_assess($auth) == 1 || $this->checkSig($params['OperatorID'], $params) == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '签名错误/Token过期或者无效', 'Ret' => 4002, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
Db::table('charge_logo')->save(['name' => $params['OperatorID'] . '推送充电结果notification_start_charge_result', 'mark' => $data]);
$data = json_decode($data, true);
if ($data['StartChargeSeqStat'] == 2) {
//充电中
$ss = [
'status' => $data['StartChargeSeqStat'],
'StartChargeSeqStat' => $data['StartChargeSeqStat'],
'start_time' => date('Y-m-d H:i:s', strtotime($data['StartTime'])),
'vin' => $data['VIN'],
];
} else {
$time = date('Y-m-d H:i:s', time());
$ss = [
'status' => $data['StartChargeSeqStat'],//充电状态
'StartChargeSeqStat' => $data['StartChargeSeqStat'],//充电状态
'start_time' => $time,
'end_time' => $time,
'stop_type' => 15,
'TotalMoney' => 0,
'TotalPower' => 0,
'IdentCode' => $data['IdentCode'] ?? '',
'vin' => $data['VIN'] ?? '',
];
}
Db::table('zxc_charge_order')->where('StartChargeSeq', $data['StartChargeSeq'])
->update($ss);
exit();
}
/**
* 查询充电状态
* 通过充电订单号查询充电状态。
* @param $StartChargeSeq string 充电订单号
* @return int[]
*
* 充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符
*
* 充电订单状态 StartChargeSeqStat 是 整型 1启动中 2充电中 3停止中 4已结束 5未知
*
* 充电设备接口编码 ConnectorID 是 字符串 参见《电动汽车充换电服务信息交换 第2部分公共信息交换规范》
*
* 充电设备接口状态 ConnectorStatus 是 整型 1空闲 2占用未充电 3占用充电中 4占用预约锁定 255故障
*
* A相电流 CurrentA 是 浮点型 单位A默认0 含直流(输出)
*
* B相电流 CurrentB 否 浮点型 单位A默认0
*
* C相电流 CurrentC 否 浮点型 单位A默认0
*
* A相电压 VoltageA 是 浮点型 单位V默认0含直流(输出)
*
* B相电压 VoltageB 否 浮点型 单位V默认0
*
* C相电压 VoltageC 否 浮点型 单位V默认0
*
* 电池剩余电量 Soc 是 浮点型 默认0
*
* 开始充电时间 StartTime 是 字符型 格式“yyyy-MM-dd HH:mm:ss”
*
* 本次采样时间 EndTime 是 字符型 格式“yyyy-MM-dd HH:mm:ss”
*
* 累计充电量 TotalPower 是 浮点型 单位小数点后3位
*
* 累计电费 ElecMoney 否 浮点型 单位小数点后2位
*
* 累计服务费 SeviceMoney 否 浮点型 单位小数点后2位
*
* 累计总金额 TotalMoney 否 浮点型 单位小数点后2位
*
* 时段数N SumPeriod 否 整型 范围032
*
* 充电明细信息 ChargeDetails 否
*
* ChargeDetails数组 单时段充电明细信息
*充电明细信息体ChargeDetails
* 参数名称 定义 必填 参数类型 描述
* 始时间 DetailStartTime 是 字符串 格式“yyyy-MM-dd HH:mm:ss”
* 结束时间 DetailEndTime 是 字符串 格式“yyyy-MM-dd HH:mm:ss”
* 时段电价 ElecPrice 否 浮点型 小数点后4位
* 时段服务费价格 SevicePrice 否 浮点型 小数点后4位
* 时段充电量 DetailPower 是 浮点型 单位小数点后3位
* 时段电费 DetailElecMoney 否 浮点型 小数点后2位
* 时段服务费 DetailSeviceMoney 否 浮点型 小数点后2位
*/
public function Get_query_equip_charge_status($StartChargeSeq)
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk['StartChargeSeq'] = $StartChargeSeq;
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_equip_charge_status ', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->Decrypt($en_mess);
Db::table('charge_logo')->insert(['mark' => $de_data, 'name' => $StartChargeSeq . ':充电状态Get_query_equip_charge_status']);
$array = json_decode($de_data, true);
if (isset($data['TotalMoney']) && $data['TotalMoney'] > 0) {
//累计金额??????
$ll = array_diff_key($array, ["ChargeDetails" => 'xy', 'StartTime' => 'xy', "StartChargeSeq" => 'xy', 'ConnectorID' => 'xy', 'TotalMoney' => 'xy']);
$charge_order_info = Db::table('zxc_charge_order')
->where('StartChargeSeq', $StartChargeSeq)
->field('openid,charge_station_id,order_number,WithholdingMoney,status, end_time')
->find();
$station_type = \app\model\ChargeStation::where('charge_station_id', $charge_order_info['charge_station_id'])->value('station_type');
$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($charge_order_info['charge_station_id'], $Details['DetailStartTime'], $Details['DetailEndTime'], $charge_order_info['openid'])['Elect'];
$S_price = $this->Rank($charge_order_info['charge_station_id'], $Details['DetailStartTime'], $Details['DetailEndTime'], $charge_order_info['openid'])['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($charge_order_info['charge_station_id'], $charge_order_info['openid']);
$total = $ll['TotalPower'] * $price['EPrice'] + ($ll['TotalPower'] * $price['SPrice']);
$ElectMoney = $array['TotalPower'] * $price['EPrice'];
$SeviceMoney = $array['TotalPower'] * $price['SPrice'];
}
if ((float)$charge_order_info['WithholdingMoney'] - (float)$total <= 3) {
Db::table('charge_logo')->save([
'name' => '检测到费用不足执行结束--查询充电状态',
'mark' => json_encode([
'WithholdingMoney' => $charge_order_info['WithholdingMoney'],
'TotalMoney' => $array['TotalMoney'],
])
]);
$order = new ChargeOrder();
$order->EndOrder2($charge_order_info['openid'], $charge_order_info['order_number']);
}
$ll['status'] = $ll['StartChargeSeqStat'];
$ll['TotalMoney'] = round($total, 2);
$ll['ElecMoney'] = round($ElectMoney, 2);
$ll['SeviceMoney'] = round($SeviceMoney, 2);
if (empty($charge_order_info['end_time']) && $charge_order_info['status'] != 4) {
Db::table('zxc_charge_order')
->where('StartChargeSeq', $StartChargeSeq)
->save($ll);
}
return ['code' => 200];
} else {
return ['code' => 1];
}
}
//查询充电状态 同上但是只返回了数据信息
public function Get_query_equip_charge_status_test($StartChargeSeq)
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$datetime = date('YmdHis');
$kk['StartChargeSeq'] = $StartChargeSeq;
$en = $this->Encrypt(json_encode($kk));
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$rr['OperatorID'] = config('hard.OperatorID');
$rr['Data'] = $en;
$rr['TimeStamp'] = $datetime;
$rr['Seq'] = config('hard.Seq');
$rr['Sig'] = $s;
$data = $rr;
$message = $this->CurlSend(config('hard.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;
// dd($array);
if (isset($array['TotalMoney'])) {
$ll = array_diff_key($array, ["ChargeDetails" => 'xy', 'StartTime' => 'xy', "StartChargeSeq" => 'xy', 'ConnectorID' => 'xy', 'TotalMoney' => 'xy']);
$station_id = Db::table('zxc_charge_order')->where('StartChargeSeq', $StartChargeSeq)->value('charge_station_id');
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
$openid = Db::table('zxc_charge_order')->where('StartChargeSeq', $StartChargeSeq)->value('openid');
$detail_message = '';
// dd($array);
if ((int)$station_type == 0) {
$ii = 1;
$total = 0;
$total_elet = 0;
$total_ser = 0;
foreach ($array['ChargeDetails'] as $Details) {
$Details = (array)$Details;
$price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $openid);
$per_price = $price['Elect'];
$S_price = $price['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;
$total_elet += $period_price;
$total_ser += $service_price;
}
} else {
$price = $this->GetPrice($station_id, $openid);
$total = $ll['TotalPower'] * $price['EPrice'] + ($ll['TotalPower'] * $price['SPrice']);
$total_elet = $ll['TotalPower'] * $price['EPrice'];
$total_ser = $ll['TotalPower'] * $price['SPrice'];
}
$ll['TotalMoney'] = round($total, 2);
$ll['ElecMoney'] = round($total_elet, 2);
$ll['SeviceMoney'] = round($total_ser, 2);
// $WithholdingMoney = Db::table($table)->where('StartChargeSeq',$StartChargeSeq)->value('WithholdingMoney');
// $openid = Db::table($table)->where('StartChargeSeq',$StartChargeSeq)->value('openid');
// $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'];
$ll['DetailMessage'] = $detail_message;
return ['code' => 200, 'data' => $ll];
// $end_time = Db::table($table)->where('order_number',$order_num)->value('end_time');
// if (empty($end_time)){
// Db::table($table)->where('StartChargeSeq',$StartChargeSeq)->update($ll);
// }
} else {
return ['code' => 1];
}
}
// 计算单个价格
public function Rank($station_id, $start, $end, $openid)
{
$start_time = date('H:i:s', strtotime($start));
$end_time = date('H:i:s', strtotime($end));
// echo $start_time;
// echo $end_time;
$interval = $this->GetPrice($station_id, $openid);
$SPrice = $interval['SPrice'];
$interval = $interval['message'];
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
if ((int)$station_type == 0) {
$i = 0;
foreach ($interval as $in) {
$st = date('H:i:s', strtotime($in['start']));
// $en = date('H:i:s',strtotime('-1 seconds',strtotime($in['end'])));
$en = date('H:i:s', strtotime($in['end']));
$check = date('H:i:s', strtotime('23:59:59'));
$check1 = date('H:i:s', strtotime('00:00:00'));
if ($i <= 7 && $start_time >= $st && $end_time <= $en && $end_time != $check1) {
return ['Elect' => $in['univalence'], 'Serve' => $SPrice];
} elseif ($i == 7 && $start_time >= $st && ($end_time <= $check || $end_time = $check1)) {
return ['Elect' => $in['univalence'], 'Serve' => $SPrice];
}
$i += 1;
}
}
}
//计算电费
public function GetPrice($station_id, $openid)
{
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
$ElectricityFee = Db::table('charge_station')->where('charge_station_id', $station_id)->value('ElectricityFee');
$type = Db::table('zxc_user')->where('openid', $openid)->value('type');
if ($type != 3) {
$ServiceFee = ServiceFee::where('type', $type)->where('station_type', $station_type)->value('service_fee');
} else {
$group_id = EnterpriseUser::where('openid', $openid)->value('group_id');
$ServiceFee = ServiceFee::where('type', $type)->where('station_type', $station_type)->where('group_id', $group_id)->value('service_fee');
}
// $ServiceFee= Db::table('charge_station')->where('charge_station_id',$station_id)->value('ServiceFee');
$ElectricityFee = str_replace('电费:', '', $ElectricityFee);
$Elect = explode(',', $ElectricityFee);
for ($index = 0; $index < count($Elect); $index++) {
$kk['time_interval'] = substr($Elect[$index], 0, 11);
$tt = explode('~', $kk['time_interval']);
$start = $tt[0] . ':00';
$end = $tt[1] ?? $tt[1] . ':00';
$kk['univalence'] = explode(':', $Elect[$index])[3];
$kk['start'] = $start;
$kk['end'] = $end;
$ss[] = $kk;
}
$ServiceFee = str_replace('服务费:', '', $ServiceFee);
$Server = explode(',', $ServiceFee);
for ($index = 0; $index < count($Server); $index++) {
$ll['time_interval'] = substr($Server[$index], 0, -5);
$ll['univalence'] = substr($Server[$index], Strlen($Server[$index]) - 4);
$mm[] = $ll;
}
if ($station_type == 1) {
return ['EPrice' => number_format((float)($ss[0]['univalence']), 6), 'SPrice' => number_format((float)($mm[0]['univalence']), 2)];
} elseif ($station_type == 0) {
return ['message' => $ss, 'SPrice' => number_format((float)($mm[0]['univalence']), 2)];
}
}
/**
* 推送充电状态
* 启动充电后,由特来电每@@@@@@五分钟@@@@@@@@推一次充电状态
* @param Request $request
* @return array|Json
*/
public function notification_equip_charge_status(Request $request)
{
$params = file_get_contents('php://input');
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$authorization = $request->header()['authorization'];//传递过来的token
$auths = explode(' ', trim($authorization));
$auth = $auths[count($auths) - 1];
$checkParams = $this->checkParams($params);
if ($checkParams != 2) {
return ['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]];
}
if (!$auth) {
return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加');
}
if ($this->checkToken_assess($auth) == 1 || $this->checkSig($params['OperatorID'], $params) == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '签名错误、Token过期或者无效', 'Ret' => 4002, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
Db::table('charge_logo')->save(['name' => '推送充电状态notification_equip_charge_status', 'mark' => $data]);
$data = json_decode($data, true);
if (isset($data['TotalMoney']) && $data['TotalMoney'] > 0) {
$array = array_diff_key($data, ["ChargeDetails" => 'xy', 'StartTime' => 'xy', 'StartChargeSeq' => 'xy', 'ConnectorID' => 'xy', 'TotalMoney' => 'xy']);
$array['start_time'] = $data['StartTime'];
$charge_order_info = Db::table('zxc_charge_order')->where('StartChargeSeq', $data['StartChargeSeq'])->find();
Db::table('charge_logo')->save(['name' => '调试数据', 'mark' => json_encode($charge_order_info)]);
$station_type = \app\model\ChargeStation::where('charge_station_id', $charge_order_info['charge_station_id'])->value('station_type');
$detail_message = '';
if ((int)$station_type == 0) {
$ii = 1;
$total = 0;
$ElectMoney = 0;
$SeviceMoney = 0;
foreach ($data['ChargeDetails'] as $Details) {
$Details = (array)$Details;
$per_price = $this->Rank($charge_order_info['charge_station_id'], $Details['DetailStartTime'], $Details['DetailEndTime'], $charge_order_info['openid'])['Elect'];
$S_price = $this->Rank($charge_order_info['charge_station_id'], $Details['DetailStartTime'], $Details['DetailEndTime'], $charge_order_info['openid'])['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($charge_order_info['charge_station_id'], $charge_order_info['openid']);
$total = $array['TotalPower'] * $price['EPrice'] + ($array['TotalPower'] * $price['SPrice']);
$ElectMoney = $data['TotalPower'] * $price['EPrice'];
$SeviceMoney = $data['TotalPower'] * $price['SPrice'];
}
$array['TotalMoney'] = round($total, 2);
$order_num = Db::table('zxc_charge_order')->where('StartChargeSeq', $data['StartChargeSeq'])->value('order_number');
if ((float)$charge_order_info['WithholdingMoney'] - (float)$array['TotalMoney'] <= 3) {
Db::table('charge_logo')->save([
'name' => '检测到费用不足执行结束--推送',
'mark' => json_encode([
'WithholdingMoney' => $charge_order_info['WithholdingMoney'],
'TotalMoney' => $array['TotalMoney'],
])
]);
$order = new ChargeOrder();
$order->EndOrder2($charge_order_info['openid'], $order_num);
}
$array['ElecMoney'] = round($ElectMoney, 2);
$array['SeviceMoney'] = round($SeviceMoney, 2);
$array['status'] = $array['StartChargeSeqStat'];
if (empty($charge_order_info['end_time']) && $charge_order_info['status'] != 4) {
Db::table('zxc_charge_order')->where('StartChargeSeq', $data['StartChargeSeq'])->save($array);
}
$kk['StartChargeSeq'] = $data['StartChargeSeq'];
$kk['SuccStat'] = 0;
return $this->encodeData($kk, $params, 0);
}
}
/**
* 接口名称请求停止充电query_stop_charge
* 接口说明:通过充电订单号、设备接口编码,请求停止充电。
* 请求格式json
* 请求方式post
* @param $StartChargeSeq string 充电订单号
* @param $ConnectorID string 充电设备接口编码
* @return array
*/
public function Get_query_stop_charge($StartChargeSeq, $ConnectorID)
{
$token = Cache::get('token');
if (!$token) {
$hardtoken = new HardToken();
$token = $hardtoken->getToken();
}
$kk = [
'StartChargeSeq' => $StartChargeSeq,
'ConnectorID' => $ConnectorID,
];
$en = $this->Encrypt(json_encode($kk));
$datetime = date('YmdHis');
$sig = config('hard.OperatorID') . $en . $datetime . config('hard.Seq');
$s = $this->HmacMD5($sig);
$data = [
'OperatorID' => config('hard.OperatorID'),
'Data' => $en,
'TimeStamp' => $datetime,
'Seq' => config('hard.Seq'),
'Sig' => $s,
];
$message = $this->CurlSend(config('hard.url') . '/query_stop_charge', $data, $token);
$en_mess = $message['Data'];
$de_data = $this->Decrypt($en_mess);
return json_decode($de_data, true);
}
/**
* 接口名称推送停止充电结果notification_stop_charge_result
* 接口说明:发起停止充电请求后,由特来电方推送停止充电结果,包括充电订单号、订单状态、充电设备接口编码、充电启动时间。
* 请求格式json
* 请求方式post
* @param Request $request
* 充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符
*
* 充电订单状态 StartChargeSeqStat 是 整型 1启动中 2充电中 3停止中 4已结束 5未知
*
* 充电设备接口编码 ConnectorID 是 字符串 格式“6位行政区编码4位电站编码3位终端编码”13位字符
*
* 成功标识 SuccStat 是 整型 0:成功; 1:失败
*
* 停止失败原因 FailReason 是 整型 0:无; 1:此设备不存在; 2:此设备离线: 3:设备已停止充电; 499:自定义
*
* @return array|Json
* 充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符与6.5.3章节相同
*
* 操作结果 SuccStat 是 整型 0:成功; 1:失败
* 失败原因 FailReason 是 整型 0:无; 1:接收失败;
*
*/
public function notification_stop_charge_result(Request $request)
{
$params = file_get_contents('php://input');
Db::table('charge_logo')->save(['name' => '推送停止充电结果notification_stop_charge_result', 'mark' => $params]);
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$authorization = $request->header()['authorization'];//传递过来的token
$auths = explode(' ', trim($authorization));
$auth = $auths[count($auths) - 1];
$checkParams = $this->checkParams($params);
if ($checkParams != 2) {
return ['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]];
}
if (!$auth) {
return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加');
}
if ($this->checkToken_assess($auth) == 1 || $this->checkSig($params['OperatorID'], $params) == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '签名错误/Token过期或者无效', 'Ret' => 4002, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
Db::table('charge_logo')->save(['name' => $params['OperatorID'] . '停止充电推送结果notification_stop_charge_result', 'mark' => $data]);
$data = json_decode($data, true);
if ($data['StartChargeSeqStat'] == 4 && $data['SuccStat'] == 0 && $data['FailReason'] == 0) {
$ss['StartChargeSeqStat'] = $data['StartChargeSeqStat'];
$ss['status'] = $data['StartChargeSeqStat'];
Db::table('zxc_charge_order')->where('StartChargeSeq', $data['StartChargeSeq'])->update($ss);
exit();
} else {
Db::table('zxc_charge_order')
->where('StartChargeSeq', $data['StartChargeSeq'])
->update(['StopFailreason' => $data['FailReason']]);
exit();
}
}
/**
* 接口名称推送充电订单信息notification_charge_order_info
* 接口说明:结束充电后,由特来电推送充电订单信息。
* 请求格式json
* 请求方式post
* @param Request $request
*充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符
*
* 充电设备接口编码 ConnectorID 是 字符串 格式“6位行政区编码4位电站编码3位终端编码”13位字符
*
* 开始充电时间 StartTime 是 字符串 格式“yyyy-MM-dd HH:mm:ss”
*
* 结束充电时间 EndTime 是 字符串 格式“yyyy-MM-dd HH:mm:ss”
*
* 累计充电量 TotalPower 是 浮点型 单位小数点后3位
*
* 总电费 TotalElecMoney 是 浮点型 单位小数点后2位
*
* 总服务费 TotalSeviceMoney 是 浮点型 单位小数点后2位
*
* 累计总金额 TotalMoney 是 浮点型 单位小数点后2位
*
* 充电结束原因 StopReason 是 整型 0:用户手动停止充电 1:客户归属地运营商平台停止充电 2BMS停止充电 3充电机设备故障 4连接器断开 5-99自定义
*
* 时段数N SumPeriod 否 整型 范围032
*
* 充电明细信息 ChargeDetails 否 ChargeDetails数组 单时段充电明细信息
* @return array|Json
*充电订单号 StartChargeSeq 是 字符串 格式“运营商ID+唯一编号”27字符
*
* 充电设备接口编码 ConnectorID 是 字符串 格式“6位行政区编码4位电站编码3位终端编码”13位字符
*
* 确认结果 ConfirmResult 是 整型 0:成功 1:争议交易 299:自定义
*/
public function notification_charge_order_info(Request $request)
{
$params = file_get_contents('php://input');
$params = json_decode($params, true);
$OperatorID = empty($params['OperatorID']) ? '' : $params['OperatorID'];
$authorization = $request->header()['authorization'];//传递过来的token
$auths = explode(' ', trim($authorization));
$auth = $auths[count($auths) - 1];
$checkParams = $this->checkParams($params);
if ($checkParams != 2) {
return ['Msg' => $checkParams . '为空', 'Ret' => 4003, 'Data' => ['Status' => 1]];
}
if (!$auth) {
return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加');
}
if ($this->checkToken_assess($auth) == 1 || $this->checkSig($params['OperatorID'], $params) == 1) {
$data = json_encode(['Status' => 1]);
$data = $this->Encrypt($data);
$seq = empty($Seq) ? '0001' : $params['Seq'];
$datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp'];
$sig = $OperatorID . $data . $datetime . $seq;
$s = $this->HmacMD5($sig);
return json(['Msg' => '签名错误、Token过期或者无效', 'Ret' => 4002, 'Data' => $data, 'Sig' => $s]);
}
$data = $this->Decrypt($params['Data']);
Db::table('charge_logo')->save(['name' => $params['OperatorID'] . '推送充电订单信息notification_charge_order_info', 'mark' => $data]);
$data = json_decode($data, true);
if (isset($data['StopReason'])) {
$StartChargeSeq = $data['StartChargeSeq'];
$charge_info = Db::table('zxc_charge_order')->where('StartChargeSeq', $StartChargeSeq)->find();
$WithholdingMoney = $charge_info['WithholdingMoney'];
$station_id = $charge_info['charge_station_id'];
$station_type = \app\model\ChargeStation::where('charge_station_id', $station_id)->value('station_type');
$detail_message = '';
if ((int)$station_type == 0) {
$ii = 1;
$total = 0;
$ElectMoney = 0;
$SeviceMoney = 0;
foreach ($data['ChargeDetails'] as $Details) {
$Details = (array)$Details;
$per_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $charge_info['openid'])['Elect'];
$S_price = $this->Rank($station_id, $Details['DetailStartTime'], $Details['DetailEndTime'], $charge_info['openid'])['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, $charge_info['openid']);
$total = $data['TotalPower'] * $price['EPrice'] + ($data['TotalPower'] * $price['SPrice']);
$ElectMoney = $data['TotalPower'] * $price['EPrice'];
$SeviceMoney = $data['TotalPower'] * $price['SPrice'];
}
$ss['end_time'] = $data['EndTime'];
$ss['TotalPower'] = $data['TotalPower'];
$TotalMoney = round($total, 2);
$ss['ElecMoney'] = round($ElectMoney, 2);
$ss['SeviceMoney'] = round($SeviceMoney, 2);
$ss['TotalMoney'] = $TotalMoney;
$ss['stop_type'] = $data['StopReason'];
$ss['SumPeriod'] = $data['SumPeriod'];
$ss['status'] = 4;
$ss['StartChargeSeqStat'] = 4;
$ss['FeedbackMoney'] = round($WithholdingMoney - $TotalMoney, 2);
$ss['DetailMessage'] = $detail_message;
$check = $charge_info['FeedbackMoney'];
if (empty($check)) {
Db::table('zxc_charge_order')->where('StartChargeSeq', $StartChargeSeq)->save($ss);
$charge_info = Db::table('zxc_charge_order')->where('StartChargeSeq', $StartChargeSeq)->find();
// 即充即退
if ($charge_info['type'] == 1 && $charge_info['directly_refund_status'] == 0 && $charge_info['is_wind'] == 0) {
$td = new WechatReimburse();
$td->Refund2($charge_info['order_id'], $charge_info['openid'], $charge_info['FeedbackMoney'], $charge_info['WithholdingMoney'], $charge_info['directly_pay_no']);
Db::table('charge_logo')->save(['name' => '充电结束即充即退执行退款', 'mark' => json_encode($charge_info)]);
}
//个人余额
if ($charge_info['type'] == 2 && $charge_info['is_wind'] == 0) {
Db::table('zxc_charge_order')->where('StartChargeSeq', $StartChargeSeq)->save(['is_wind'=>1]);
\app\model\User::addMoneyLog($charge_info['openid'], $TotalMoney, 1, '充电结束执行用户使用个人钱包充电' . $ss['FeedbackMoney']);
Db::table('zxc_user')->where('openid', $charge_info['openid'])->update(['account' => Db::raw('account-' . $TotalMoney)]);
}
}
Log::error('充电结束' . json_encode($data), 'error');
exit();
}
}
}