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) { if ($this->checkToken_assess($auth) == 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]); } $checkSig = $this->checkSig($params['OperatorID'], $params); if ($checkSig == 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' => '签名错误', 'Ret' => 4001, 'Data' => $data, 'Sig' => $s]); } $data = $this->Decrypt($params['Data']); $data = json_decode($data, true); if (isset($data['vin']) && isset($data['connectorID'])) { Log::write("The Plug Message come on :" . $data['vin'] . $data['connectorID']); $CheckVinIsExist = Db::table('vinlicense')->where('EvcInfoNo', $data['vin'])->find(); if (!empty($CheckVinIsExist)) { $AppointmentTime = Db::table('appointment_time')->where('id', 1)->value('AppointmentTime'); $currentDate = new DateTime(); $combinedDateTime = new DateTime($currentDate->format('Y-m-d') . ' ' . $AppointmentTime); $AppointmentTime = $combinedDateTime->format('Y-m-d H:i:s'); $nowTime = $currentDate->format('Y-m-d H:i:s'); $nowDay = $currentDate->format('Y-m-d'); $check = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->where('ConnectorID', $data['connectorID'])->find(); if (empty($check)) { Db::table('appointment')->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID'], 'Vin' => $data['vin'], 'plug_time' => $AppointmentTime]); } // $check = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->find(); // if (empty($check)) { // Db::table('appointment')->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID'], 'Vin' => $data['vin'], 'plug_time' => $AppointmentTime]); // } else { // $checkVin = Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->value('ConnectorID'); // if ($checkVin != $data['connectorID']) { // Db::table('appointment')->whereDay('action_time', $nowDay)->where('Vin', $data['vin'])->save(['action_time' => $nowTime, 'ConnectorID' => $data['connectorID']]); // } // } } $kk['SuccStat'] = 0; $kk['FailReason'] = 0; return $this->encodeData($kk, $params, 0); } else { $kk['SuccStat'] = 1; $kk['FailReason'] = 1; return $this->encodeData($kk, $params, 0); } } return $this->encodeData(['Status' => 1], $params, 4002, 'Bearer 未添加'); // $OperatorID = Config::get('hard.OperatorID'); // $OperatorSecret = Config::get('hard.OperatorSecret'); } public function PlugGennerateOrder($ConnectorID, $vin): array { $station_id = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('charge_station_id'); $EquipAuthSeq = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('EquipAuthSeq'); $no = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('no'); if (empty($EquipAuthSeq)) { $EquipAuthSeq = $this->generate_EquipmentAuth(7); Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->update(['EquipAuthSeq' => $EquipAuthSeq]); } $Hard = new HardMessage(); $openid = 'o-wLg5DGWU_rYwfmp1-1Wck1lKGw'; $area = Db::table('user')->where('openid', $openid)->value('area'); $pinyin = new Pinyin(); $s = $pinyin->sentence($area); $s = strtr($s, array(' ' => '')); $table = 'charge_order_' . $s; $table_user = 'user_' . $s; $AuthMessage = $Hard->Get_query_equip_auth($EquipAuthSeq, $ConnectorID); if (isset($AuthMessage['FailReason']) && isset($AuthMessage['SuccStat'])) {//认证成功 请求启动充电 if ($AuthMessage['FailReason'] == 0 && $AuthMessage['SuccStat'] == 0) { $StartChargeSeq = $this->generate_StartChargeSeq(7); ChargeOrderModel::insert(['openid' => $openid, 'area' => $area, 'StartChargeSeq' => $StartChargeSeq]); $ChargeModel = 1; $StartCharge = $Hard->Get_query_start_charge_test($StartChargeSeq, $ConnectorID, 'QRCode', $ChargeModel, $vin); //ChargeModel vin if ($StartCharge['StartChargeSeqStat'] == 1 && $StartCharge['SuccStat'] == 0 && $StartCharge['FailReason'] == 0) { $order_number = $this->generate_order(6); $charge_date = date('Y-m-d', time()); $account = 200; $Equipment_number = Db::table('charge_pile')->where('ConnectorID', $ConnectorID)->value('charge_pile_number'); $mess = [ 'order_number' => $order_number, 'charge_station_id' => $station_id, 'openid' => $openid, 'charge_date' => $charge_date, 'Equipment_number' => $Equipment_number, 'StartChargeSeq' => $StartChargeSeq, 'status' => $StartCharge['StartChargeSeqStat'], 'StartChargeSeqStat' => $StartCharge['StartChargeSeqStat'], 'ConnectorID' => $ConnectorID, 'WithholdingMoney' => $account, 'EvcInfoNo' => $vin ]; Db::table($table_user)->where('openid', $openid)->update(['account' => Db::raw('account-' . $account)]); Db::table($table)->save($mess); $time = date('Y-m-d H:i:s'); Log::write('Reservation order has been generated. The Message is ' . $time . json($mess)->getContent()); return ['code' => 200, 'message' => '订单创建成功', 'order_number' => $order_number]; } elseif ($StartCharge['SuccStat'] == 1) { if ($StartCharge['FailReason'] == 0) { return ['code' => 1, 'message' => '设备认证操作结果失败']; } elseif ($StartCharge['FailReason'] == 1) { return ['code' => 1, 'message' => '设备认证操作结果失败 此设备不存在']; } elseif ($StartCharge['FailReason'] == 2) { return ['code' => 1, 'message' => '设备认证操作结果失败 此设备离线']; } elseif ($StartCharge['FailReason'] == 90) { return ['code' => 1, 'message' => '设备认证操作结果失败 车辆未备案']; } elseif ($StartCharge['FailReason'] == 91) { return ['code' => 2, 'message' => '设备认证操作结果失败 该车辆充电中']; } else { return ['code' => 1, 'message' => '未知错误 设备认证成功 请求充电失败']; } } else { return ['code' => 1, 'message' => '未知错误 设备认证成功 请求充电失败']; } } elseif ($AuthMessage['SuccStat'] == 1) { if ($AuthMessage['FailReason'] == 0) { return ['code' => 1, 'message' => '设备认证操作结果失败']; } elseif ($AuthMessage['FailReason'] == 1) { return ['code' => 1, 'message' => '设备认证操作结果失败 此设备尚未插枪']; } elseif ($AuthMessage['FailReason'] == 2) { return ['code' => 1, 'message' => '设备认证操作结果失败 设备检测失败']; } else { return ['code' => 1, 'message' => '未知错误 设备认证失败']; } } else { return ['code' => 1, ' message' => '未知错误 设备认证失败']; } } else { return ['code' => 1, 'message' => '未知错误 设备认证失败']; } } public function ModifyAppointmentTime($time): \think\response\Json { $dateTime = new DateTime($time); $formattedTime = $dateTime->format('H:i:s'); $modify = Db::table('appointment_time')->where('id', 1)->save(['AppointmentTime' => $formattedTime]); if ((int)$modify == 1) { return json(['code' => 200, 'msg' => '修改成功']); } else { return json(['code' => 1, 'msg' => '修改失败']); } } public function ShowAppointmentTime(): \think\response\Json { $AppointmentTime = Db::table('appointment_time')->where('id', 1)->value('AppointmentTime'); return json(['code' => 200, 'msg' => '显示成功', 'data' => $AppointmentTime]); } private function generate_StartChargeSeq($length): string { $chars = '0123456789'; $time = time(); $password = config('hard.OperatorID') . $time . '2';//2代表是生成的充电订单号 for ($i = 0; $i < $length; $i++) { $password .= $chars[mt_rand(0, strlen($chars) - 1)]; } return $password; } private function generate_order($length): string { $chars = '0123456789'; $time = time(); $password = 'DZZS' . $time; for ($i = 0; $i < $length; $i++) { $password .= $chars[mt_rand(0, strlen($chars) - 1)]; } return $password; } private function generate_EquipmentAuth($length): string { $chars = '0123456789'; $time = time(); $password = config('hard.OperatorID') . $time . '1';//1代表是生成的设备认证流水号 for ($i = 0; $i < $length; $i++) { $password .= $chars[mt_rand(0, strlen($chars) - 1)]; } return $password; } public function Encrypt($data): string { $aes = new Aes(); return $aes->encrypt($data); } private function Decrypt($data) { $aes = new Aes(); return $aes->decrypt($data); } private function HmacMD5($data): string { $md5 = new HMACMD5(); return $md5->HMAC($data); } private function CurlSend($url, $data = '', $token = '') { $data = json_encode($data); // echo $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); } private function checkParams($params) { $arr = ['OperatorID', 'Data', 'TimeStamp', 'Seq', 'Sig']; // 参数检查 foreach ($arr as $v) { if (empty($params[$v])) { return $v; } } return 2; } private function checkSig($OperatorID, $params): int { $sig = $OperatorID . $params['Data'] . $params['TimeStamp'] . $params['Seq']; $ecry_sig = $this->HmacMD5($sig); if ($params['Sig'] != $ecry_sig) { return 1; } return 2; } public function signToken(): string { $key = config('hard.DataSecretIV'); //这里是自定义的一个随机字串,应该写在config文件中的,解密时也会用,相当 于加密中常用的 盐 salt $token = array( "iss" => $key, //签发者 可以为空 "aud" => '', //面象的用户,可以为空 "iat" => time(), //签发时间 "nbf" => time() + 1, //在什么时候jwt开始生效 (这里表示生成100秒后才生效) "exp" => time() + 7200, //token 过期时间 "data" => [ //记录的userid的信息,这里是自已添加上去的,如果有其它信息,可以再添加数组的键值对 'name' => 'zuxing' ] ); // print_r($token); $jwt = JWT::encode($token, $key, "HS256"); //根据参数生成了 token return $jwt; } //验证token private function checkToken_assess($token): int { $key = config('hard.DataSecretIV'); $key = new Key($key, 'HS256'); $status = array("code" => 2); try { JWT::$leeway = 60;//当前时间减去60,把时间留点余地 $decoded = JWT::decode($token, $key, array('HS256')); //HS256方式,这里要和签发的时候对应 $arr = (array)$decoded; $res['code'] = 1; $res['data'] = $arr['data']; return 2; } catch (\Firebase\JWT\SignatureInvalidException $e) { //签名不正确 $status['msg'] = "签名不正确"; return 1; } catch (\Firebase\JWT\BeforeValidException $e) { // 签名在某个时间点之后才能用 $status['msg'] = "token失效"; return 1; } catch (\Firebase\JWT\ExpiredException $e) { // token过期 $status['msg'] = "token失效"; return 1; } catch (\Exception $e) { //其他错误 $status['msg'] = "未知错误"; return 1; } } private function encodeData($data, $params, $ret, $msg = ''): \think\response\Json { $data = json_encode($data); $data = $this->Encrypt($data); $seq = empty($Seq) ? '0001' : $params['Seq']; $datetime = empty($TimeStamp) ? date('YmdHis') : $params['TimeStamp']; $sig = $params['OperatorID'] . $data . $datetime . $seq; $s = $this->HmacMD5($sig); return json(['Msg' => $msg, 'Ret' => $ret, 'Data' => $data, 'Sig' => $s]); } }