Commit b891742b by banice

init

parents
REDIS_HOST=redis.test.senthink.com
REGISTER_IP=127.0.0.1
REGISTER_PORT=1239
GATEWAY_PORT=8282
GATEWAY_IP=127.0.0.1
GATEWAY_COUNT=1
GATEWAY_START_PORT=2130
START_FILE=business|gateway|register
DB_HOST=db.test.senthink.com
DB_USERNAME=cdz
DB_DATABASE=cdzpay
DB_PORT=3306
DB_PASSWORD=senthink123
RABBIT_HOST=rabbitmq.test.senthink.com
RABBIT_PORT=5672
RABBIT_LOGIN=rabbitmq
RABBIT_PASSWORD=senthink123!
RABBIT_VHOST=cdz_gateway
REDIS_PORT=6379
LOG_LEVEL=debug
MESSAGE_API_URL=https://cdzback2.test.senthink.com
MESSAGE_START=L9SEWl3X73v3PBYHtFBZlTlJeBMdO9DDNIwRgHX6SrY
MESSAGE_FAIL=0al-a6kkNsdqFyXPEe97m4jjtbfOXjEC3eCjEsMHJdw
MESSAGE_POWER_EXCEED=rdzTNQ7t4uRXkP0SkuwW10WH77A_CIgYFiJykXJ0utU
REDIS_HOST=redis.test.senthink.com
REGISTER_IP=127.0.0.1
REGISTER_PORT=1239
GATEWAY_PORT=8282
GATEWAY_IP=127.0.0.1
GATEWAY_COUNT=1
GATEWAY_START_PORT=2130
START_FILE=business|gateway|register
DB_HOST=db.test.senthink.com
DB_USERNAME=cdz
DB_DATABASE=cdzpay
DB_PORT=3306
DB_PASSWORD=senthink123
RABBIT_HOST=rabbitmq.test.senthink.com
RABBIT_PORT=5672
RABBIT_LOGIN=rabbitmq
RABBIT_PASSWORD=senthink123!
RABBIT_VHOST=cdz_gateway
REDIS_PORT=6379
LOG_LEVEL=debug
MESSAGE_API_URL=https://cdzback2.test.senthink.com
MESSAGE_START=L9SEWl3X73v3PBYHtFBZlTlJeBMdO9DDNIwRgHX6SrY
MESSAGE_FAIL=0al-a6kkNsdqFyXPEe97m4jjtbfOXjEC3eCjEsMHJdw
MESSAGE_POWER_EXCEED=rdzTNQ7t4uRXkP0SkuwW10WH77A_CIgYFiJykXJ0utU
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" packagePrefix="Lib\" />
<sourceFolder url="file://$MODULE_DIR$/application" isTestSource="false" packagePrefix="Application\" />
<sourceFolder url="file://$MODULE_DIR$/route" isTestSource="false" packagePrefix="Route\" />
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
<excludeFolder url="file://$MODULE_DIR$/vendor/workerman/gateway-worker" />
<excludeFolder url="file://$MODULE_DIR$/vendor/workerman/mysql" />
<excludeFolder url="file://$MODULE_DIR$/vendor/workerman/workerman" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
</state>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData" serverName="ftp">
<serverData>
<paths name="ftp">
<serverdata>
<mappings>
<mapping deploy="/test/cdzbusinessv2" local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptSettings">
<option name="languageLevel" value="ES6" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cdz_gateway_v2.iml" filepath="$PROJECT_DIR$/.idea/cdz_gateway_v2.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpIncludePathManager">
<include_path>
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
<path value="$PROJECT_DIR$/vendor/composer" />
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
<path value="$PROJECT_DIR$/vendor/workerman/workerman" />
<path value="$PROJECT_DIR$/vendor/workerman/mysql" />
<path value="$PROJECT_DIR$/vendor/workerman/gateway-worker" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebServers">
<option name="servers">
<webServer id="fb88f314-fdf2-4d0f-9384-9631bc16b852" name="ftp" url="http://10.120.66.207">
<fileTransfer host="10.120.66.207" port="21">
<advancedOptions>
<advancedOptions dataProtectionLevel="Private" passiveMode="true" />
</advancedOptions>
<option name="port" value="21" />
</fileTransfer>
</webServer>
</option>
</component>
</project>
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 下午2:55
*/
use Workerman\MySQL\Connection;
use Lib\Crc;
use Lib\log\Log;
use Application\route\Api;
use Src\route\Route;
use Lib\station\gateway\Gateway;
use Lib\station\gateway\port\Port;
class Events
{
/**
* @var Connection
*/
private static $db;
/**
* @var \Redis
*/
private static $redis;
public static function onWorkerStart()
{
static::$db = new Connection(getenv('DB_HOST'), getenv('DB_PORT'), getenv('DB_USERNAME'), getenv('DB_PASSWORD'), getenv('DB_DATABASE'));
static::$redis = new \Redis();
static::$redis->pconnect(getenv('REDIS_HOST'), getenv('REDIS_PORT'), 0);
if (getenv('REDIS_AUTH') !== false) {
static::$redis->auth(getenv('REDIS_AUTH'));
}
static::$redis->select('4');
}
public static function onConnect($clientId)
{
}
/**
* 验证message
* 提取command字段
* 查找路由,验证路由
* 按照路由创建控制器和执行方法
* 日志收集
* @param $clientId
* @param $message
*/
public static function onMessage($clientId, $message)
{
var_dump($message);
$crc = substr($message, -2);
$crcConfirm = sprintf('%08x', Crc::crc(substr($message, 0, strlen($message) - 2)));
if ($crc != mb_strtoupper(substr($crcConfirm, 0, 2))) {
Log::error("message crc wrong ($message)");
return;
}
$command = substr($message, 6, 2);
if (isset(Api::$route[$command])) {
$route = Api::$route[$command];
if ($route instanceof Route) {
$reflection = $route->getController();
$controller = $reflection->newInstanceArgs([$clientId, $message, $route]);
$method = $route->getMethod();
try {
$controller->$method();
} catch (Exception $exception) {
Log::error($exception->getMessage());
}
}
}
}
public static function onClose($clientId)
{
Events::pipe();
$gatewayId = $_SESSION['gateway_id'];
$gateway = new Gateway();
//网关状态设置为离线
$gateway->setState($gatewayId, 0);
$portsMacId = $_SESSION['port_mac_id'];
$portsId = array_values($portsMacId);
$port = new Port();
foreach ($portsId as $portId) {
$port->setPortId($portId);
$port->setState(10);
$port->updatePortState();
}
//所有端口状态设置为离线
Events::exec();
//端口当前订单记录离线时间
}
/**
*
*/
public static function pipe()
{
static::$redis->multi(2);
}
/**
*
*/
public static function exec()
{
static::$redis->exec();
}
/**
* @return Redis
*/
public static function getRedis()
{
return static::$redis;
}
/**
* @return Connection
*/
public static function getDb()
{
return static::$db;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 上午10:49
*/
namespace Application\controller;
use Src\request\Request;
use Src\response\Response;
use Src\route\Route;
class Controller
{
/**
* 数据帧解析
* @var array
*/
protected $parameterMap = [];
/**
* 客户端id
*
* @var string
*/
protected $clientId;
/**
* 接受到的消息
*
* @var string
*/
protected $message;
/**
* 请求对象
*
* @var Request
*/
protected $request;
/**
* 是否加密
*
* @var bool
*/
protected $encrypt = false;
/**
* 数据帧基本结构
*
* @var array
*/
protected $defaultHeader = [
'preamble' => 2,
'headerFlag' => 1,
'headerCtrl' => 1,
'length' => 2,
'nonce' => 1,
];
/**
* 数据头
*
* @var string
*/
protected $preamble;
/**
* 是否加密字段
*
* @var string
*/
protected $headerFlag;
/**
* 消息命令
*
* @var string
*/
protected $headerCtrl;
/**
* 数据帧长度
*
* @var string
*/
protected $length;
/**
* 数据帧中的随机字符
*
* @var string
*/
protected $nonce;
/**
* 数据头
*
* @var array
*/
protected $headerBody = [];
/**
* 响应实例
*
* @var Response
*/
protected $response;
/**
* @var int
*/
protected $plc = 0;
protected $route;
public function __construct(string $clientId, string $message, Route $route)
{
$this->clientId = $clientId;
$this->message = $message;
$this->route = $route;
$this->parseHeader($message, $this->defaultHeader);
$this->parseBody();
$this->response = new Response($this);
$this->encrypt = $this->headerFlag === '05' ? true : false;
}
/**
*
*/
private function parseBody()
{
$tmp = [];
foreach ($this->parameterMap[$this->route->getCommand()] as $key => $length) {
$start = $this->plc;
$length *= 2;
$tmp[$key] = substr($this->message, $start, $length);
$this->plc += $length;
}
$this->request = new Request($tmp);
}
private function parseHeader(string $message, array $map)
{
$parameters = [];
$start = 0;
foreach ($map as $key => $length) {
$length *= 2;
$parameters[$key] = substr($message, $start, $length);
if (property_exists($this, $key)) {
$this->$key = $parameters[$key];
}
$start += $length;
$this->plc += $length;
}
return $parameters;
}
/**
* Get 数据帧解析
*
* @return array
*/
public function getParameterMap()
{
return $this->parameterMap;
}
/**
* Set 数据帧解析
*
* @param array $parameterMap 数据帧解析
*
* @return self
*/
public function setParameterMap(array $parameterMap)
{
$this->parameterMap = $parameterMap;
return $this;
}
/**
* Get 客户端id
*
* @return string
*/
public function getClientId()
{
return $this->clientId;
}
/**
* Set 客户端id
*
* @param string $clientId 客户端id
*
* @return self
*/
public function setClientId(string $clientId)
{
$this->clientId = $clientId;
return $this;
}
/**
* Get 接受到的消息
*
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Set 接受到的消息
*
* @param string $message 接受到的消息
*
* @return self
*/
public function setMessage(string $message)
{
$this->message = $message;
return $this;
}
/**
* Get 请求对象
*
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Set 请求对象
*
* @param Request $request 请求对象
*
* @return self
*/
public function setRequest(Request $request)
{
$this->request = $request;
return $this;
}
/**
* Get 是否加密
*
* @return bool
*/
public function getEncrypt()
{
return $this->encrypt;
}
/**
* Set 是否加密
*
* @param bool $encrypt 是否加密
*
* @return self
*/
public function setEncrypt(bool $encrypt)
{
$this->encrypt = $encrypt;
return $this;
}
/**
* Get 数据帧基本结构
*
* @return array
*/
public function getDefaultHeader()
{
return $this->defaultHeader;
}
/**
* Set 数据帧基本结构
*
* @param array $defaultHeader 数据帧基本结构
*
* @return self
*/
public function setDefaultHeader(array $defaultHeader)
{
$this->defaultHeader = $defaultHeader;
return $this;
}
/**
* Get 响应实例
*
* @return Response
*/
public function getResponse()
{
return $this->response;
}
/**
* Set 响应实例
*
* @param Response $response 响应实例
*
* @return self
*/
public function setResponse(Response $response)
{
$this->response = $response;
return $this;
}
/**
* Get 消息命令
*
* @return string
*/
public function getHeaderCtrl()
{
return $this->headerCtrl;
}
/**
* Set 消息命令
*
* @param string $headerCtrl 消息命令
*
* @return self
*/
public function setHeaderCtrl(string $headerCtrl)
{
$this->headerCtrl = $headerCtrl;
return $this;
}
/**
* Get 数据帧长度
*
* @return string
*/
public function getLength()
{
return $this->length;
}
/**
* Set 数据帧长度
*
* @param string $length 数据帧长度
*
* @return self
*/
public function setLength(string $length)
{
$this->length = $length;
return $this;
}
/**
* Get 数据头
*
* @return string
*/
public function getPreamble()
{
return $this->preamble;
}
/**
* Set 数据头
*
* @param string $preamble 数据头
*
* @return self
*/
public function setPreamble(string $preamble)
{
$this->preamble = $preamble;
return $this;
}
/**
* Get 数据帧中的随机字符
*
* @return string
*/
public function getNonce()
{
return $this->nonce;
}
/**
* Set 数据帧中的随机字符
*
* @param string $nonce 数据帧中的随机字符
*
* @return self
*/
public function setNonce(string $nonce)
{
$this->nonce = $nonce;
return $this;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午4:06
*/
namespace Application\controller;
use Src\route\Route;
class HeartController extends Controller
{
const GATEWAY_LAST_HEART_TIME = 'cdz:gateway:heart:last_time:hash';
const GATEWAY_HEART_TIMES = 'cdz:gateway:heart_times:zset';
protected $parameterMap = [
'00' => [
]
];
public function __construct(string $clientId, string $message, Route $route)
{
parent::__construct($clientId, $message, $route);
}
public function break()
{
$time = time();
$redis = \Events::getRedis();
$redis->hSet(self::GATEWAY_LAST_HEART_TIME,$_SESSION['gateway_id'],$time);
$redis->zIncrBy(self::GATEWAY_HEART_TIMES,1,$_SESSION['gateway_id']);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午2:22
*/
namespace Application\controller\accept;
use Application\controller\Controller;
use Application\model\DeviceModel;
use Application\model\GatewayModel;
use Lib\cdz\order\Order;
use Lib\cdz\order\state\OfflineNetState;
use Lib\cdz\order\state\OfflinePowerState;
use Lib\Gateway;
use Lib\StateCode;
use Lib\station\gateway\port\Port;
use Src\route\Route;
class AccessController extends Controller
{
protected $parameterMap = [
'02' => [
'mac' => 6,
],
'03' => [
'logic_start' => 1,
'count' => 1,
'total_count' => 1,
]
];
public function __construct(string $clientId, string $message, Route $route)
{
parent::__construct($clientId, $message, $route);
}
/**
* 请求入网
* 网关下的所有端口id和mac写如session
*/
public function request(): void
{
$mac = $this->request->get('mac');
$gatewayModel = new GatewayModel();
if (isset($_SESSION['gateway_mac'])) {
if ($_SESSION['gateway_mac'] != $mac) {
Gateway::closeClient($this->clientId);
}
$gatewayModelResult = $gatewayModel->getColumns([
'station_id',
'id',
], 'mac_address = ' . "'$mac'");
if (count($gatewayModelResult) === 0) {
Gateway::closeClient($this->clientId);
}
$stationId = $gatewayModelResult['station_id'];
$gatewayId = $gatewayModelResult['id'];
$deviceModel = new DeviceModel();
$deviceModelResult = $deviceModel->getAllColumns([
'id',
'device_mac',
], 'gateway_id = ' . $gatewayId);
$tmp = [];
foreach ($deviceModelResult as $item) {
$tmp[$item['device_mac']] = $item['id'];
}
$_SESSION['port_mac_id'] = $tmp;
$_SESSION['port_id_mac'] = array_flip($tmp);
var_dump($tmp);
$_SESSION['station_id'] = $stationId;
$_SESSION['gateway_id'] = $gatewayId;
$_SESSION['client_id'] = $this->clientId;
$sessionId = '';
for ($i = 0; $i < 4; $i++) {
$hex = sprintf('%02x', rand(0, 255));
$sessionId .= $hex;
}
$gateway = new \Lib\station\gateway\Gateway();
$gateway->setState($gatewayId,1);
$this->response->send('02', $sessionId);
}
}
/**
* 同步口子
* 逻辑地址存入数据库和redis
* 同步端口状态
* 端口存在正在充电的订单根据离线原因计算剩余充电时间
* 若已经退款的订单则同步完成后下发结束充电
*
*/
public function syncPort(): void
{
$logicStart = hexdec($this->request->get('logic_start'));
$count = hexdec($this->request->get('count'));
$totalCount = hexdec($this->request->get('total_count'));
$portMacState = [];
for ($i = 0; $i < $count; $i++) {
$mac = substr($this->message, $this->plc, 8 * 2);
$this->plc += 16;
$state = substr($this->message, $this->plc, 2);
$portMacState[$mac] = hexdec($state);
}
$portsMacId = $_SESSION['port_mac_id'];
\Events::pipe();
$port = new Port();
$portsLogicId = [];
$portsId = array_values($portsMacId);
foreach ($portMacState as $mac => $state) {
$portId = isset($portsMacId[$mac]) ? $portsMacId[$mac] : false;
if ($portId === false) {
continue;
}
$port->setPortId($portId);
//设置端口状态
$port->setState($state);
$port->setGatewayId($_SESSION['gateway_id']);
$port->setStationId($_SESSION['station_id']);
$port->updatePortState();
$portsLogicId[$portId] = $logicStart++;
}
\Events::exec();
$deviceModel = new DeviceModel();
$_SESSION['port_logic_id'] = $portsLogicId;
//更新逻辑地址
foreach ($portsLogicId as $portId => $logicId)
{
$deviceModel->update(['logic_num' => $logicId],'id = '.$portId);
}
$order = new Order();
$responseOrder = [];
$offlineReason = hexdec(substr($this->message, $this->plc, 2));
foreach ($portsId as $portId) {
$port->setPortId($portId);
$orderId = $port->getPortUsingOrderId();
if($orderId == false || $orderId == '')
{
continue;
}
$order->setId($orderId);
if($order->getOrderCache(\Events::getRedis()) ==false)
{
continue;
}
if($offlineReason === 1)
{
$orderState = new OfflinePowerState($order);
}else{
$orderState = new OfflineNetState($order);
}
$portState = $portMacState[$_SESSION['port_id_mac'][$portId]];
$remainTime = $orderState->getRemainChargerTime();
if($remainTime > 0)
{
$logicNum = sprintf('%02x',$order->getPortLogicId());
$orderId = sprintf('%012x',$order->getId());
$time = sprintf('%04x',$remainTime);
array_push($responseOrder,$logicNum.$orderId.$time);
}
$logicStart = sprintf('%02x',$logicStart);
$count = sprintf('%02x',$count);
$totalCount = sprintf('%02x',$totalCount);
$orderCount = sprintf('%02x',count($responseOrder));
$this->response->send('03',$logicStart.$count.$totalCount.$orderCount.implode('',$responseOrder));;
}
}
}
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 下午3:29
*/
namespace Application\controller\accept;
use Application\controller\Controller;
use Application\model\DeviceModel;
use Lib\Aes;
use GatewayWorker\Lib\Gateway;
use Src\route\Route;
/**
* 设备认证
* Class CertifyController
* @package Application\controller\accept
*/
class CertifyController extends Controller
{
protected $parameterMap = [
'01' => [
'mac' => 6,
],
];
public function __construct(string $clientId, string $message, Route $route)
{
parent::__construct($clientId, $message, $route);
}
public function certify()
{
$nonce = $this->getNonce();
$mac = $this->request->get('mac');
$_SESSION['gateway_mac'] = $mac;
$_SESSION['certified'] = true;
$productId = 'A22E4F4CDB05C460E450E46241DD6F89';
$sign = bin2hex(Aes::encrypt($nonce, $productId));
$sign = substr($sign, 0, 8);
if (Gateway::isUidOnline($mac) === 1) {
$clients = Gateway::getclientIdByUid($mac);
foreach ($clients as $client) {
Gateway::closeClient($client);
}
}
Gateway::bindUid($this->clientId,$mac);
$this->response->send('01', $sign);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午4:06
*/
namespace Application\controller\business\charger;
use Application\controller\Controller;
class OverController extends Controller
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午3:54
*/
namespace Application\controller\business\charger;
use Application\controller\Controller;
use Lib\cdz\order\Order;
use Lib\cdz\order\state\WaitingState;
use Lib\StateCode;
class StartController extends Controller
{
protected $parameterMap = [
'04' => [
'type' => 1,
'logic_id' => 1,
'state' => 1,
'order_id' => 6,
'capacity' => 4,
],
];
/**
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function start()
{
$type = hexdec($this->getRequest()->get('type'));
$logic = $this->getRequest()->get('logic_id');
$state = hexdec($this->getRequest()->get('state'));
$orderId = hexdec($this->getRequest()->get('order_id'));
$capacity = hexdec($this->getRequest()->get('capacity'));
if ($type == 1) {
$waitingState = new WaitingState(new Order($orderId));
switch ($state) {
case StateCode::PORT_CHARGER:
$waitingState->toChargerState();
break;
case StateCode::PORT_EXCEPTION:
$waitingState->toExceptionState();
break;
case StateCode::PORT_SHED:
$waitingState->toShedState();
break;
case StateCode::FINISH_EXCEED:
$waitingState->toPowerExceedState();
break;
default:
break;
}
}
$this->response->send('04',sprintf('%012x',$orderId));
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午4:06
*/
namespace Application\controller\business\port;
use Application\controller\Controller;
use Lib\cdz\order\Order;
use Lib\cdz\order\state\ChargerState;
use Lib\cdz\order\state\ExceptionState;
use Lib\cdz\order\state\PowerExceedState;
use Lib\cdz\order\state\ShedState;
use Lib\StateCode;
use Lib\station\gateway\port\Port;
class StateController extends Controller
{
protected $parameterMap = [
'0b' => [
'port_logic' => 1,
'mac' => 8,
'state' => 1,
]
];
public function change()
{
$portLogic = $this->request->get('port_logic');
$mac = $this->request->get('mac');
$state = $this->request->get('state');
$portsMacId = $_SESSION['port_mac_id'];
$portId = $portsMacId[$mac];
$port = new Port($portId);
$usingOrder = $port->getPortUsingOrderId();
if ($usingOrder == false || $usingOrder = '') {
$port->setState($state);
$port->updatePortState();
} else {
$order = new Order($usingOrder);
if ($order->getOrderCache(\Events::getRedis()) == false) {
$port->setState($state);
$port->updatePortState();
return;
}
switch ($order->getStateCode()) {
case StateCode::PORT_CHARGER:
$orderState = new ChargerState($order);
break;
case StateCode::CHARGER_SHED:
$orderState = new ShedState($order);
break;
case StateCode::FINISH_EXCEED:
$orderState = new PowerExceedState($order);
break;
case StateCode::PORT_EXCEPTION:
$orderState = new ExceptionState($order);
break;
default:
return;
}
switch ($state) {
case StateCode::PORT_CHARGER:
$orderState->toChargerState();
break;
case StateCode::FINISH_EXCEED:
$orderState->toPowerExceedState();
break;
default :
break;
}
}
}
}
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午4:36
*/
namespace Application\controller\business\power;
use Application\controller\Controller;
use Application\model\OrderModel;
use Application\model\OrderPowerModel;
use Lib\cdz\order\Order;
use Lib\station\gateway\port\Port;
class PowerController extends Controller
{
protected $parameterMap = [
'17' => [
'logic_id' => 1,
'power' => 2,
'capacity' => 4,
],
'07' => [
'logic_id' => 1,
'start_time' => 4,
'interval_time' => 1,
'count' => 1,
]
];
public function one()
{
$logicId = hexdec($this->request->get('logic_id'));
$power = hexdec($this->request->get('power'));
$capacity = hexdec($this->request->get('capacity'));
$portsLogicId = array_flip($_SESSION['port_id_logic']);
if (isset($portsLogicId[$logicId])) {
$portId = $portsLogicId[$logicId];
$port = new Port($portId);
$orderId = $port->getPortUsingOrderId();
if ($orderId == false || $orderId == '') {
return;
}
$order = new Order($orderId);
if ($order->getOrderCache(\Events::getRedis()) != false) {
if ($order->getStartCapacity() === -1) {
$orderModel = new OrderModel();
$orderModel->update(['start_capacity' => $capacity], 'id = ' . $orderId);
}
}
$orderPowerModel = new OrderPowerModel();
$orderPowerModel->insertRow([
'order_id' => $orderId,
'capacity' => $capacity,
'power' => $power,
'port_id' => $portId,
'created_at' => date('Y-m-d H:i:s'),
]);
}
}
public function plural()
{
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午2:29
*/
namespace Application\model;
class DeviceModel extends Model
{
protected $table = 'devices';
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午2:24
*/
namespace Application\model;
class GatewayModel extends Model
{
protected $table = 'gateways';
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:48
*/
namespace Application\model;
use Workerman\MySQL\Connection;
class Model
{
/**
* @var Connection
*/
protected $db;
protected $table;
/**
* Model constructor.
*/
public function __construct()
{
$this->db = \Events::getDb();
}
/**
* @param $column
* @param $where
* @return string
*/
public function getColumn($column, $where)
{
$where .= ' AND deleted_at IS NULL';
return $this->db->single("SELECT $column FROM $this->table WHERE $where");
}
/**
* @param array $columns
* @param $where
* @return array
*/
public function getColumns(Array $columns, $where)
{
$columns = implode(',', $columns);
$where .= ' AND deleted_at IS NULL';
return $this->db->row("SELECT $columns FROM $this->table WHERE $where");
}
/**
* @param array $columns
* @param $where
* @return mixed
*/
public function getAllColumns(Array $columns, $where)
{
$columns = implode(',', $columns);
$where .= ' AND deleted_at IS NULL';
return $this->db->query("SELECT $columns FROM $this->table WHERE $where");
}
/**
* @param $where
* @return array
*/
public function getRow($where)
{
return $this->db->row("SELECT * FROM $this->table WHERE $where");
}
/**
* @param array $data
* @return mixed
*/
public function insertRow(Array $data)
{
return $this->db->insert($this->table)->cols($data)->query();
}
/**
* @param array $update
* @param $where
* @return mixed
*/
public function update(array $update, $where)
{
return $this->db->update($this->table)->cols($update)->where($where)->query();
}
}
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:57
*/
namespace Application\model;
class OrderExceptionModel extends Model
{
protected $table = 'wx_charger_orders_exception';
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:50
*/
namespace Application\model;
class OrderModel extends Model
{
protected $table = 'wx_charger_orders';
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午9:22
*/
namespace Application\model;
class OrderPowerModel extends Model
{
protected $table = 'order_power_capacity';
}
\ No newline at end of file
<?php
namespace Application\route;
use Application\controller\Controller;
use Src\route\Route;
class Api
{
public static $route = [];
public static function boot()
{
static::add('01', 'accept\CertifyController@certify');
static::add('00','HeartController@break');
static::add('02','accept\AccessController@request');
static::add('03','accept\AccessController@syncPort');
static::add('0b','business\port\StateController@change');
}
/**
* 添加路由
*
* @param string $command
* @param string $controllerAction
* @param array $middlewar
* @return void
*/
public static function add(string $command, string $controllerAction, array $middleware = [])
{
$route = new Route();
$route->setCommand($command);
if (strstr($controllerAction, '@')) {
$controllerAction = explode('@', $controllerAction);
try {
$controllerName = 'Application\\controller\\' . $controllerAction[0];
$controller = new \ReflectionClass($controllerName);
$route->setController($controller);
$methods = $controller->getMethods(\ReflectionMethod::IS_PUBLIC);
$result = false;
foreach ($methods as $method) {
if ($method->name === $controllerAction[1]) {
$result = true;
}
}
if ($result === false) {
exit($controllerAction[1] . 'method not find');
}
$route->setMethod($controllerAction[1]);
unset($controller);
} catch (\ReflectionException $exception) {
exit(__CLASS__ . '-->' . $exception->getMessage());
}
static::$route[$command] = $route;
} else {
exit('wrong route missing controller');
}
unset($route);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 上午11:05
*/
$worker = new \GatewayWorker\BusinessWorker();
$worker->name = 'cdz_business';
$worker->count = 4;
$worker->registerAddress = getenv('REGISTER_IP') . ':' . getenv('REGISTER_PORT');
$logs = fopen('./storage/logs/business.log','w');
fclose($logs);
\GatewayWorker\BusinessWorker::$stdoutFile = './storage/stdout.log';
\GatewayWorker\BusinessWorker::$logFile = './storage/logs/business.log';
if (!defined('GLOBAL_START')) {
\Workerman\Worker::runAll();
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 上午11:05
*/
$gateway = new \GatewayWorker\Gateway('bintohex://0.0.0.0:' . getenv('GATEWAY_PORT'));
$gateway->name = 'cdz';
$gateway->count = getenv('GATEWAY_COUNT');
$gateway->lanIp = getenv('GATEWAY_IP');
$gateway->startPort = getenv('GATEWAY_START_PORT');
$gateway->registerAddress = getenv('REGISTER_IP') . ':' . getenv('REGISTER_PORT');
// 心跳间隔
$gateway->pingInterval = 45;
// 心跳数据
$gateway->pingNotResponseLimit = 2;
if (!defined('GLOBAL_START')) {
\Workerman\Worker::runAll();
}
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 上午11:05
*/
$register = new \GatewayWorker\Register('text://' . getenv('REGISTER_IP') . ':' . getenv('REGISTER_PORT'));
if (!defined('GLOBAL_START')) {
\Workerman\Worker::runAll();
}
\ No newline at end of file
{
"require": {
"workerman/gateway-worker": "^3.0",
"workerman/mysql": "^1.0",
"monolog/monolog": "^1.23",
"guzzlehttp/guzzle": "^6.3",
"vlucas/phpdotenv": "^2.5"
},
"autoload": {
"psr-4": {
"Application\\": "application/",
"Lib\\":"lib/",
"Route\\":"route/",
"Src\\" :"src/"
}
}
}
This diff is collapsed. Click to expand it.
/storage/
/.env
/.idea/
<?php
namespace Lib;
class Aes{
public static function encrypt($data,$key)
{
return openssl_encrypt(hex2bin($data),'aes-128-ecb',hex2bin($key),1);
}
public static function decrypt($data,$key)
{
return openssl_decrypt(hex2bin($data),'aes-128-ecb',hex2bin($key),1);
}
}
\ No newline at end of file
<?php
namespace Lib;
class Crc
{
const CRC_TABLE = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
];
/**
* @param $data
* @return int
*/
public static function crc($data)
{
$crc = 0xffffffff;
$size = strlen($data);
for($i=0;$i<$size;$i+=2)
{
$numHex = substr($data,$i,2);
$number = hexdec($numHex);
$tmp = ($crc^$number) & 0xff;
$crcRightMove = (hexdec(sprintf("%08x",$crc>>8)));
$crc = ($crcRightMove)^(self::CRC_TABLE[$tmp]);
}
return $crc ^ 0xffffffff;
}
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:51
*/
namespace Lib;
class StateCode
{
const WAITING = -1;
const PORT_OFFLINE = 10;
const PORT_ONLINE = 11;
const PORT_CHARGER = 12;
const PORT_EXCEPTION = 13;
const PORT_SHED = 14;
const CHARGER_FAIL = 21;
const CHARGER_SHED = 22;
const CHARGER_SUCCESS = 23;
const FINISH_TIME_END = 30;
const FINISH_REMOTE = 31;
const FINISH_SHED = 32;
const FINISH_FULL = 33;
const FINISH_EXCEED = 34;
const FINISH_FAIL = 35;
const FINISH_CHARGER = 36;
const FINISH_USER = 41;
const FINISH_SHED_TIMEOUT = 42;
const FINISH_REFUND = 43;
const FINISH_EXCEPTION_REFUND = 44;
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午7:07
*/
namespace Lib\cdz\order;
use Lib\rabbitmq\PublishPortShed;
trait NoticePortShed
{
/**
* @param Order $order
* @throws \AMQPConnectionException
* @throws \AMQPExchangeException
*/
public function publishPortShed(Order $order)
{
$publishPortShed = new PublishPortShed();
$publishPortShed->publishOrder([
'order_id' => $order->getId(),
'time' => date('Y-m-d H:i:s'),
'gateway_mac' => $order->getGatewayMac(),
'shed_time' => time()
]);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:29
*/
namespace Lib\cdz\order;
use Lib\cdz\order\state\State;
class Order
{
use StopCharger;
const ORDER_HASH_PREFIX = 'cdz:order:state:';
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $createdTime = '';
/**
* @var int
*/
private $purchaseTime;
/**
* @var string
*/
private $startTime;
/**
* @var string
*/
private $finishTime;
/**
* @var string
*/
private $shedTime;
/**
* @var string
*/
private $offlineTime;
/**
* @var string
*/
private $onlineTime;
/**
* 订单状态
* @var int
*/
private $stateCode;
/**
* @var int
*/
private $userId;
/**
* @var int
*/
private $payAmount;
/**
* @var int
*/
private $portId;
/**
* @var int
*/
private $gatewayId;
/**
* @var string
*/
private $gatewayMac;
/**
* @var int
*/
private $portLogicId;
/**
* @var array
*/
private $orderCache;
/**
* @var string
*/
private $portName;
/**
* @var string
*/
private $stationName;
/**
* @var int
*/
private $startCapacity = -1;
/**
* @var int
*/
private $endCapacity = -1;
/**
* @var string
*/
private $outTradeNo;
/**
* @var int
*/
private $isRefund = 0;
/**
* @param $name
* @return string
*/
public function __get($name)
{
return isset($this->$name) ? $this->$name : '';
}
public function __construct(int $orderId = 0) {
$this->id = $orderId;
}
/**
*
* @param \Redis $redis
* @return array|bool
*/
public function getOrderCache(\Redis $redis)
{
if (isset($this->orderCache) == false || (is_array($this->orderCache) && count($this->orderCache) === 0)) {
$keyName = $this->getCacheKeyName();
if ($redis->exists($keyName) == false) {
return false;
}
$this->orderCache = $redis->hGetAll($keyName);
var_dump($this->orderCache);
foreach ($this->orderCache as $key => $value) {
$this->$key = $value;
}
}
return $this->orderCache;
}
/**
* @param \Redis $redis
* @return array|bool
*/
public function refreshOrderCache(\Redis $redis)
{
$keyName = $this->getCacheKeyName();
if ($redis->exists($keyName) == false) {
return false;
}
$this->orderCache = $redis->hGetAll($keyName);
foreach ($this->orderCache as $key => $value) {
$this->$key = $value;
}
return $this->orderCache;
}
/**
* @param \Redis $redis
* @param $orderCache
*/
public function setOrderCache(\Redis $redis, $orderCache): void
{
$this->orderCache = $orderCache;
}
/**
* @return int
*/
public function getStateCode(): int
{
return $this->stateCode;
}
/**
* @param int $stateCode
*/
public function setStateCode(int $stateCode): void
{
$this->stateCode = $stateCode;
}
/**
* @return string
*/
public function getCreatedTime(): string
{
return $this->createdTime;
}
/**
* @param string $createdTime
*/
public function setCreatedTime(string $createdTime): void
{
$this->createdTime = $createdTime;
}
/**
* @return int
*/
public function getUserId(): int
{
return $this->userId;
}
/**
* @param int $userId
*/
public function setUserId(int $userId): void
{
$this->userId = $userId;
}
/**
* @return int
*/
public function getPayAmount(): int
{
return $this->payAmount;
}
/**
* @param int $payAmount
*/
public function setPayAmount(int $payAmount): void
{
$this->payAmount = $payAmount;
}
/**
* @return int
*/
public function getPurchaseTime(): int
{
return $this->purchaseTime;
}
/**
* @param int $purchaseTime
*/
public function setPurchaseTime(int $purchaseTime): void
{
$this->purchaseTime = $purchaseTime;
}
/**
* @return int
*/
public function getPortId(): int
{
return $this->portId;
}
/**
* @param int $portId
*/
public function setPortId(int $portId): void
{
$this->portId = $portId;
}
/**
* @return int
*/
public function getGatewayId(): int
{
return $this->gatewayId;
}
/**
* @param int $gatewayId
*/
public function setGatewayId(int $gatewayId): void
{
$this->gatewayId = $gatewayId;
}
/**
* @return int
*/
public function getId(): int
{
return $this->id;
}
/**
* @param int $id
*/
public function setId(int $id): void
{
$this->id = $id;
}
/**
* @return string
*/
public function getGatewayMac(): string
{
return $this->gatewayMac;
}
/**
* @param string $gatewayMac
*/
public function setGatewayMac(string $gatewayMac): void
{
$this->gatewayMac = $gatewayMac;
}
/**
* @return int
*/
public function getPortLogicId(): int
{
return isset($this->portLogicId) ? (int)$this->portLogicId : 0;
}
/**
* @param int $portLogicId
*/
public function setPortLogicId(int $portLogicId): void
{
$this->portLogicId = $portLogicId;
}
/**
* @return string
*/
public function getPortName(): string
{
return $this->portName;
}
/**
* @param string $portName
*/
public function setPortName(string $portName): void
{
$this->portName = $portName;
}
/**
* @return string
*/
public function getStationName(): string
{
return $this->stationName;
}
/**
* @param string $stationName
*/
public function setStationName(string $stationName): void
{
$this->stationName = $stationName;
}
/**
* @return int
*/
public function getStartCapacity(): int
{
return $this->startCapacity;
}
/**
* @param int $startCapacity
*/
public function setStartCapacity(int $startCapacity): void
{
$this->startCapacity = $startCapacity;
}
/**
* @return int
*/
public function getEndCapacity(): int
{
return $this->endCapacity;
}
/**
* @param int $endCapacity
*/
public function setEndCapacity(int $endCapacity): void
{
$this->endCapacity = $endCapacity;
}
/**
* @return string
*/
public function getOutTradeNo(): string
{
return $this->outTradeNo;
}
/**
* @param string $outTradeNo
*/
public function setOutTradeNo(string $outTradeNo): void
{
$this->outTradeNo = $outTradeNo;
}
/**
* @return int
*/
public function getIsRefund(): int
{
return $this->isRefund;
}
/**
* @param int $isRefund
*/
public function setIsRefund(int $isRefund): void
{
$this->isRefund = $isRefund;
}
public function getCacheKeyName()
{
return self::ORDER_HASH_PREFIX . $this->id;
}
/**
* @return string
*/
public function getStartTime(): string
{
return $this->startTime;
}
/**
* @param string $startTime
*/
public function setStartTime(string $startTime): void
{
$this->startTime = $startTime;
}
/**
* @return string
*/
public function getFinishTime(): string
{
return $this->finishTime;
}
/**
* @param string $finishTime
*/
public function setFinishTime(string $finishTime): void
{
$this->finishTime = $finishTime;
}
/**
* @return string
*/
public function getShedTime(): string
{
return $this->shedTime;
}
/**
* @param string $shedTime
*/
public function setShedTime(string $shedTime): void
{
$this->shedTime = $shedTime;
}
/**
* @return string
*/
public function getOfflineTime(): string
{
return $this->offlineTime;
}
/**
* @param string $offlineTime
*/
public function setOfflineTime(string $offlineTime): void
{
$this->offlineTime = $offlineTime;
}
/**
* @return string
*/
public function getOnlineTime(): string
{
return $this->onlineTime;
}
/**
* @param string $onlineTime
*/
public function setOnlineTime(string $onlineTime): void
{
$this->onlineTime = $onlineTime;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午6:50
*/
namespace Lib\cdz\order;
use Src\command\SendCommand;
use Src\command\StopChargerCommand;
trait StopCharger
{
/**
* 结束订单命令
* @param Order $order
* @param string $clientId
* @param int $finishType
*/
public function stop(Order $order,string $clientId, int $finishType = 0)
{
$stopChargerCommand = new StopChargerCommand();
$stopChargerCommand->setOutTradeNo($order->getId());
$stopChargerCommand->setPortLogic($order->getPortLogicId());
$stopChargerCommand->setFinishType($finishType);
$sendCommand = new SendCommand($stopChargerCommand);
$sendCommand->send($clientId);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 上午10:30
*/
namespace Lib\cdz\order\save;
use Lib\cdz\order\Order;
class OrderSaveRedis
{
/**
* @var Order
*/
private $order;
/**
* @var \Redis
*/
private $redis;
public function __construct(Order $order)
{
$this->redis = \Events::getRedis();
$this->order = $order;
}
public function save(array $keys)
{
$update = [];
foreach ($keys as $key) {
if ($this->order->$key !== "") {
$update[$key] = $this->order->$key;
}
}
$this->redis->hMset($this->order->getCacheKeyName(), $update);
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:21
*/
namespace Lib\cdz\order\state;
use Application\model\OrderExceptionModel;
use Application\model\OrderModel;
use Lib\log\Log;
use Lib\remote\api\message\ChargerFullMessage;
use Lib\remote\api\message\PowerExceedMessage;
use Lib\remote\api\message\SendMessage;
use Lib\StateCode;
use Lib\station\gateway\port\Port;
class ChargerState extends State
{
public function toWaitingState()
{
Log::error('charger state can not change to waiting state');
// TODO: Implement toWaitingState() method.
}
public function toChargerState()
{
Log::error('charger state can not change to charger state');
// TODO: Implement toChargerState() method.
}
public function toExceptionState()
{
// TODO: Implement toExceptionState() method.
}
/**
* 开始充电后功率过大
* 修改订单状态
* 推送消息
* 更新口子状态释放订单
* 记录订单异常
*
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function toPowerExceedState()
{
//更新订单状态
$orderModel = new OrderModel();
$orderModel->update([
'is_stop' => StateCode::FINISH_EXCEED,
'end_capacity' => $this->order->getEndCapacity(),
'end_time' => date('Y-m-d H:i:s', $this->nowTimeStamp),
'state' => 1,
], 'id = ' . $this->order->getId());
$orderExceptionModel = new OrderExceptionModel();
$orderExceptionModel->insertRow([
'order_id' => $this->order->getId(),
'state' => StateCode::PORT_CHARGER . StateCode::FINISH_EXCEED,
'desc' => '功率超限',
'created_at' => date('Y-m-d H:i:s', $this->nowTimeStamp),
]);
$powerExceedMessage = new PowerExceedMessage();
$powerExceedMessage->setUserId($this->order->getUserId());
$powerExceedMessage->setStartTime($this->order->getStartTime());
$powerExceedMessage->setEndTime(date('Y-m-d H:i:s', $this->nowTimeStamp));
$powerExceedMessage->setChargerTime($this->order->getPurchaseTime());
$powerExceedMessage->setRemark($powerExceedMessage->getRemark() . '\n' . sprintf('%012x', $this->order->getId()));
$sendMessage = new SendMessage();
if ($sendMessage->request($powerExceedMessage) === false) {
Log::error('send power exceed message fail');
//todo tcp异常上报
}
$port = new Port();
$port->setPortId($this->order->getPortId());
$port->freePort();
}
/**
* 充满自停
* 修改订单状态
* 记录订单异常
* 推送消息
* 释放口子
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function toPowerFullState()
{
$orderModel = new OrderModel();
$orderModel->update([
'is_stop' => StateCode::FINISH_FULL,
'end_time' => $this->nowDate,
'end_capacity' => $this->order->getEndCapacity(),
'state' => 1,
], 'id = ' . $this->order->getId());
$orderExceptionModel = new OrderExceptionModel();
$orderExceptionModel->insertRow([
'order_id' => $this->order->getId(),
'state' => StateCode::PORT_CHARGER . StateCode::FINISH_FULL,
'desc' => '订单充电自停',
'created_at' => $this->nowDate,
]);
$chargerFullMessage = new ChargerFullMessage();
$chargerFullMessage->setEndTime($this->nowDate);
$chargerFullMessage->setStartTime($this->order->getStartTime());
$chargerFullMessage->setPurchaseTime($this->order->getPurchaseTime());
$chargerFullMessage->setRemark($chargerFullMessage->getRemark() . '\n' . sprintf('%012x', $this->order->getId()));
$sendMessage = new SendMessage();
if ($sendMessage->request($chargerFullMessage) === false) {
Log::error('send charger full message fail');
}
$port = new Port();
$port->setPortId($this->order->getPortId());
$port->freePort();
}
public function toShedState()
{
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
// TODO: Implement toTimeoutState() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:22
*/
namespace Lib\cdz\order\state;
use Lib\cdz\order\Order;
class ExceptionState extends State
{
public function __construct(Order $order)
{
parent::__construct($order);
}
public function toWaitingState()
{
// TODO: Implement toWaitingState() method.
}
public function toChargerState()
{
// TODO: Implement toChargerState() method.
}
public function toExceptionState()
{
// TODO: Implement toExceptionState() method.
}
public function toPowerExceedState()
{
// TODO: Implement toPowerExceedState() method.
}
public function toPowerFullState()
{
// TODO: Implement toPowerFullState() method.
}
public function toShedState()
{
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
// TODO: Implement toTimeoutState() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午6:45
*/
namespace Lib\cdz\order\state;
use Lib\cdz\order\NoticePortShed;
use Lib\cdz\order\Order;
class OfflineNetState extends State
{
use NoticePortShed;
/**
* @var int
*/
private $remainChargerTime = 0;
public function __construct(Order $order)
{
parent::__construct($order);
$startTime = $this->order->getStartTime();
$purchaseTime = $this->order->getPurchaseTime();
$this->remainChargerTime = $purchaseTime *60 - ((int)$this->order->getOnlineTime() - $startTime);
$this->remainChargerTime = (int)($this->remainChargerTime/60);
}
public function toWaitingState()
{
// TODO: Implement toWaitingState() method.
}
public function toChargerState()
{
if($this->order->getIsRefund() === 1)
{
//已经退款 下发结束充电命令
$this->order->stop($this->order,$_SESSION['client_id'],43);
return;
}
}
public function toExceptionState()
{
// TODO: Implement toExceptionState() method.
}
public function toPowerExceedState()
{
// TODO: Implement toPowerExceedState() method.
}
public function toPowerFullState()
{
// TODO: Implement toPowerFullState() method.
}
/**
* @throws \AMQPConnectionException
* @throws \AMQPExchangeException
*/
public function toShedState()
{
if($this->remainChargerTime > 0)
{
$this->publishPortShed($this->order);
}
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
// TODO: Implement toTimeoutState() method.
}
/**
* @return int
*/
public function getRemainChargerTime(): int
{
return $this->remainChargerTime;
}
/**
* @param int $remainChargerTime
*/
public function setRemainChargerTime(int $remainChargerTime): void
{
$this->remainChargerTime = $remainChargerTime;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午6:45
*/
namespace Lib\cdz\order\state;
use Lib\cdz\order\Order;
class OfflinePowerState extends State
{
public function __construct(Order $order)
{
parent::__construct($order);
}
/**
* @var int
*/
private $remainChargerTime =0;
public function toWaitingState()
{
// TODO: Implement toWaitingState() method.
}
public function toChargerState()
{
if($this->order->getIsRefund() === 1)
{
//已经退款 下发结束充电命令
//$this->order->stop($this->order,$_SESSION['client_id'],43);
$this->remainChargerTime = 0;
return;
}
$offlineTime = $this->order->getOfflineTime();
$startTime = $this->order->getStartTime();
$purchaseTime = $this->order->getPurchaseTime();
$this->remainChargerTime = $purchaseTime *60- ($offlineTime - $startTime);
$this->remainChargerTime = (int)($this->remainChargerTime/60);
}
public function toExceptionState()
{
// TODO: Implement toExceptionState() method.
}
public function toPowerExceedState()
{
// TODO: Implement toPowerExceedState() method.
}
public function toPowerFullState()
{
// TODO: Implement toPowerFullState() method.
}
public function toShedState()
{
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
// TODO: Implement toTimeoutState() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:22
*/
namespace Lib\cdz\order\state;
use Lib\cdz\order\Order;
class PowerExceedState extends State
{
public function __construct(Order $order)
{
parent::__construct($order);
}
public function toWaitingState()
{
// TODO: Implement toWaitingState() method.
}
public function toChargerState()
{
// TODO: Implement toChargerState() method.
}
public function toExceptionState()
{
// TODO: Implement toExceptionState() method.
}
public function toPowerExceedState()
{
// TODO: Implement toPowerExceedState() method.
}
public function toPowerFullState()
{
// TODO: Implement toPowerFullState() method.
}
public function toShedState()
{
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
// TODO: Implement toTimeoutState() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:22
*/
namespace Lib\cdz\order\state;
class PowerFullState
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:21
*/
namespace Lib\cdz\order\state;
use Lib\cdz\order\Order;
class ShedState extends State
{
public function __construct(Order $order)
{
parent::__construct($order);
}
public function toWaitingState()
{
// TODO: Implement toWaitingState() method.
}
public function toChargerState()
{
// TODO: Implement toChargerState() method.
}
public function toExceptionState()
{
// TODO: Implement toExceptionState() method.
}
public function toPowerExceedState()
{
// TODO: Implement toPowerExceedState() method.
}
public function toPowerFullState()
{
// TODO: Implement toPowerFullState() method.
}
public function toShedState()
{
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
// TODO: Implement toTimeoutState() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:23
*/
namespace Lib\cdz\order\state;
class ShedTimeoutState
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:21
*/
namespace Lib\cdz\order\state;
use Lib\cdz\order\Order;
abstract class State
{
/**
* @var State
*/
protected $currentState;
/**
* @var Order
*/
protected $order;
/**
* @var int
*/
protected $nowTimeStamp;
/**
* @var string
*/
protected $nowDate;
public function __construct(Order $order)
{
$this->nowTimeStamp = time();
$this->nowDate = date('Y-m-d H:i:s', $this->nowTimeStamp);
$this->order = $order;
}
public abstract function toWaitingState();
public abstract function toChargerState();
public abstract function toExceptionState();
public abstract function toPowerExceedState();
public abstract function toPowerFullState();
public abstract function toShedState();
public abstract function toShedTimeoutState();
public abstract function toTimeoutState();
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:23
*/
namespace Lib\cdz\order\state;
class TimeoutState
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/13
* Time: 上午11:21
*/
namespace Lib\cdz\order\state;
use Application\model\OrderExceptionModel;
use Application\model\OrderModel;
use Lib\cdz\order\Order;
use Lib\cdz\order\save\OrderSaveRedis;
use Lib\Gateway;
use Lib\log\Log;
use Lib\remote\api\message\FailMessage;
use Lib\remote\api\message\SendMessage;
use Lib\remote\api\message\StartMessage;
use Lib\StateCode;
use Lib\station\gateway\port\Port;
use Src\command\SendCommand;
use Src\command\StopChargerCommand;
class WaitingState extends State
{
public function __construct(Order $order)
{
parent::__construct($order);
}
public function toWaitingState()
{
}
public function toRefundFinish()
{
//更新订单状态
$orderModel = new OrderModel();
$orderModel->update([
'is_stop' => StateCode::FINISH_REFUND,
'end_capacity' => $this->order->getEndCapacity(),
'end_time' => date('Y-m-d H:i:s'),
],'id = '.$this->order->getId());
//释放端口
}
/**
*
* 开始充电
* 更新订单的cache
* 更新数据库中订单
* 推送开始充电消息
* 订单轨迹记录
* 更新端口状态
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function toChargerState(): void
{
//订单已经退款则直接结束
if($this->order->getIsRefund() == 1)
{
//todo 下发结束充电命令
$orderId = $this->order->getId();
$portLogic = $this->order->getPortLogicId();
$finishType = 43;
$stopChargerCommand = new StopChargerCommand();
$stopChargerCommand->setFinishType($finishType);
$stopChargerCommand->setPortLogic($portLogic);
$stopChargerCommand->setOutTradeNo($orderId);
$sendCommand = new SendCommand($stopChargerCommand);
$sendCommand->send($_SESSION['client_id']);
return;
}
//更新订单cache
$this->order->setStartTime($this->nowTimeStamp);
$this->order->setStateCode(12);
\Events::pipe();
$orderSaveRedis = new OrderSaveRedis($this->order);
$orderSaveRedis->save(['stateCode', 'startTime']);
//更新口子状态
$port = new Port();
$port->setPortId($this->order->getPortId());
$port->setState(StateCode::PORT_CHARGER);
$port->setGatewayId($this->order->getGatewayId());
$port->setStationId($_SESSION['station_id']);
$port->updatePortState();
\Events::exec();
//推送消息
$startMessage = new StartMessage();
$startMessage->setUserId($this->order->getUserId());
$startMessage->setAmount($this->order->getPayAmount());
$startMessage->setAddress($this->order->getStationName() . '--' . $this->order->getPortName());
$startMessage->setRemark($startMessage->getRemark() . sprintf('%012x', $this->order->getId()));
$sendMessage = new SendMessage();
if ($sendMessage->request($startMessage) === false) {
Log::error('推送开始充电失败');
}
//更新订单状态
$update = [
'is_charger' => StateCode::PORT_CHARGER,
'start_time' => date('Y-m-d H:i:s', $this->order->getStartTime()),
'start_capacity' => $this->order->getStartCapacity(),
];
$orderModel = new OrderModel();
$orderModel->update($update, 'id = ' . $this->order->getId());
$orderExceptionModel = new OrderExceptionModel();
//添加订单异常
$orderExceptionModel->insertRow([
'order_id' => $this->order->getId(),
'state' => '-1' . StateCode::PORT_CHARGER,
'desc' => '开始充电',
'created_at' => date('Y-m-d H:i:s', $this->order->getStartTime()),
]);
}
/**
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function toExceptionState(): void
{
//更新订单状态
$orderModel = new OrderModel();
$orderModel->update([
'is_charger' => StateCode::PORT_EXCEPTION,
], 'id = ' . $this->order->getId());
//添加订单异常
$orderExceptionModel = new OrderExceptionModel();
$orderExceptionModel->insertRow([
'order_id' => $this->order->getId(),
'state' => '-1' . StateCode::PORT_EXCEPTION,
'desc' => '打开口子失败',
'created_at' => date('Y-m-d H:i:s'),
]);
//推送消息
$failMessage = new FailMessage();
$failMessage->setAddress($this->order->getStationName() . '--' . $this->order->getPortName());
$failMessage->setAddress($this->order->getPayAmount());
$failMessage->setUserId($this->order->getUserId());
$sendMessage = new SendMessage();
if ($sendMessage->request($failMessage) === false) {
Log::error('充电失败,推送消息失败', $this->order->getOrderCache(\Events::getRedis()));
}
//更新口子状态
$port = new Port();
$port->setPortId($this->order->getPortId());
$port->setState(StateCode::PORT_EXCEPTION);
$port->updatePortState();
// TODO: Implement toExceptionState() method.
}
/**
* 功率超限
*/
public function toPowerExceedState()
{
// TODO: Implement toPowerExceedState() method.
}
public function toPowerFullState()
{
Log::error('waiting state can not change to power full state');
// TODO: Implement toPowerFullState() method.
}
public function toShedState()
{
// TODO: Implement toShedState() method.
}
public function toShedTimeoutState()
{
Log::error('waiting state can not change to shed timeout');
// TODO: Implement toShedTimeoutState() method.
}
public function toTimeoutState()
{
Log::error('waiting state can not change to timeout state');
// TODO: Implement toTimeoutState() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 上午9:41
*/
namespace Lib\log;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;
/**
*
* @method static debug($info, $context = [])
* @method static warn($info, $context = [])
* @method static alert($info, $context = [])
* @method static error($info, $context = [])
* @method static info($info, $context = [])
*
*
* Class Log
* @package Lib
*/
class Log
{
/**
* @var Logger
*/
private static $log;
const LOG_NAME = './storage/logs/gateway';
private function __construct(string $logName)
{
}
public static function bootLog(string $logName = './storage/logs/gateway')
{
if (static::$log instanceof Log) {
return static::$log;
} else {
static::$log = new Logger($logName);
}
}
/**
* @param $name
* @param $arguments
*/
public static function __callStatic($name, $arguments)
{
$gatewayMac = isset($_SESSION['gateway_mac']) ? $_SESSION['gateway_mac'] : 'null mac';
$handle = new RotatingFileHandler(self::LOG_NAME);
$output = "[%datetime%] [%$gatewayMac%].%level_name%: %message% %context% %extra%\n";
$handle->setFormatter(new LineFormatter($output, 'Y-m-d H:i:s'));
return call_user_func_array([static::$log, $name], $arguments);
}
}
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/10
* Time: 上午9:41
*/
namespace Lib\log;
class Record
{
/**
* @var string
*/
private $time;
/**
* @var string
*/
private $type;
/**
* @var string
*/
private $level;
/**
* @var string
*/
private $source;
/**
* @var mixed
*/
private $content;
public function __construct()
{
$this->time = time();
}
/**
* @return string
*/
public function getTime()
{
return $this->time;
}
/**
* @param string $time
*/
public function setTime($time)
{
$this->time = $time;
}
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param string $type
*/
public function setType($type)
{
$this->type = $type;
}
/**
* @return string
*/
public function getLevel()
{
return $this->level;
}
/**
* @param string $level
*/
public function setLevel($level)
{
$this->level = $level;
}
/**
* @return string
*/
public function getSource()
{
return $this->source;
}
/**
* @param string $source
*/
public function setSource($source)
{
$this->source = $source;
}
/**
* @return mixed
*/
public function getContent()
{
return $this->content;
}
/**
* @param mixed $content
*/
public function setContent($content)
{
$this->content = $content;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午7:09
*/
namespace Lib\rabbitmq;
use Lib\log\Log;
class MyRabbitMq
{
/**
* @var \AMQPConnection
*/
protected $connection;
/**
* @var \AMQPChannel
*/
protected $channel;
/**
* @var string
*/
protected $routeKey;
/**
* @var string
*/
protected $exchangeKey;
/**
* @var \AMQPExchange
*/
protected $exchange;
/**
* MyRabbitMq constructor.
* @throws \AMQPConnectionException
* @throws \AMQPExchangeException
*/
public function __construct()
{
$this->connection = new \AMQPConnection([
'host' => getenv('RABBIT_HOST'),
'port' => getenv('RABBIT_PORT'),
'login' => getenv('RABBIT_LOGIN'),
'password' => getenv('RABBIT_PASSWORD'),
'vhost' => getenv('RABBIT_VHOST'),
]);
if (!$this->connection->connect()) {
Log::error('rabbit mq connect fail');
throw new \Exception('amqp connect fail');
} else {
$this->channel = new \AMQPChannel($this->connection);
$this->exchange = new \AMQPExchange($this->channel);
}
}
/**
* @return \AMQPChannel
* @throws \AMQPConnectionException
*/
public function getChannel(): \AMQPChannel
{
return $this->channel = new \AMQPChannel($this->connection);
}
/**
* @return \AMQPConnection
*/
public function getConnection(): \AMQPConnection
{
return $this->connection;
}
/**
* @param \AMQPConnection $connection
*/
public function setConnection(\AMQPConnection $connection)
{
$this->connection = $connection;
}
/**
* @return string
*/
public function getRouteKey(): string
{
return $this->routeKey;
}
/**
* @param string $routeKey
*/
public function setRouteKey(string $routeKey)
{
$this->routeKey = $routeKey;
}
/**
* @return string
*/
public function getExchangeKey(): string
{
return $this->exchangeKey;
}
/**
* @param string $exchangeKey
*/
public function setExchangeKey(string $exchangeKey)
{
$this->exchangeKey = $exchangeKey;
}
/**
* @return \AMQPExchange
*/
public function getExchange(): \AMQPExchange
{
return $this->exchange;
}
/**
* @param \AMQPExchange $exchange
*/
public function setExchange(\AMQPExchange $exchange)
{
$this->exchange = $exchange;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/20
* Time: 下午7:09
*/
namespace Lib\rabbitmq;
use Lib\log\Log;
class PublishPortShed
{
/**
* PublishPortShed constructor.
* @throws \AMQPConnectionException
* @throws \AMQPExchangeException
*/
public function __construct() {
$this->rabbitMq = new MyRabbitMq();
$this->exchange = $this->rabbitMq->getExchange();
$this->exchange->setName('cdz_gateway');
$this->exchange->setType(AMQP_EX_TYPE_DIRECT);
$this->exchange->setFlags(AMQP_DURABLE);
try {
$this->exchange->declareExchange();
} catch (\AMQPChannelException $e) {
Log::error($e->getMessage());
} catch (\AMQPConnectionException $e) {
Log::error($e->getMessage());
} catch (\AMQPExchangeException $e) {
Log::error($e->getMessage());
}
}
public function publishOrder(array $message, string $routeKey = 'delay_check_port_charger_state')
{
try {
return $this->exchange->publish(json_encode($message), $routeKey, AMQP_MANDATORY);
} catch (\AMQPChannelException $e) {
} catch (\AMQPConnectionException $e) {
} catch (\AMQPExchangeException $e) {
}
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/18
* Time: 上午11:11
*/
namespace Lib\remote\api\message;
class ChargerFullMessage extends Message
{
protected $templateId = '';
private $first = '尊敬的用户,您的爱车已充满电,本次充电已结束';
private $startTime = '';
private $endTime = '';
private $purchaseTime;
private $remark = '温馨提示:您的爱车已停止充电,如有疑问您可以在公众号后台留言或直接拨打客服热线进行咨询。
感谢您的使用';
public function getPushJson(): string
{
return json_encode([
'first' => [
'value' => $this->first,
'color' => '#333',
],
'keyword1' => [
'value' => $this->startTime,
'color' => '#333',
],
'keyword2' => [
'value' => $this->purchaseTime,
'color' => '#333',
],
'keyword3' => [
'value' => $this->endTime,
'color' => '#333',
],
'remark' => [
'value' => $this->remark,
'color' => '#333',
],
]);
}
/**
* @return string
*/
public function getTemplateId(): string
{
return $this->templateId;
}
/**
* @param string $templateId
*/
public function setTemplateId(string $templateId): void
{
$this->templateId = $templateId;
}
/**
* @return string
*/
public function getFirst(): string
{
return $this->first;
}
/**
* @param string $first
*/
public function setFirst(string $first): void
{
$this->first = $first;
}
/**
* @return string
*/
public function getStartTime(): string
{
return $this->startTime;
}
/**
* @param string $startTime
*/
public function setStartTime(string $startTime): void
{
$this->startTime = $startTime;
}
/**
* @return string
*/
public function getEndTime(): string
{
return $this->endTime;
}
/**
* @param string $endTime
*/
public function setEndTime(string $endTime): void
{
$this->endTime = $endTime;
}
/**
* @return mixed
*/
public function getPurchaseTime()
{
return $this->purchaseTime;
}
/**
* @param mixed $purchaseTime
*/
public function setPurchaseTime($purchaseTime): void
{
$this->purchaseTime = $purchaseTime;
}
/**
* @return string
*/
public function getRemark(): string
{
return $this->remark;
}
/**
* @param string $remark
*/
public function setRemark(string $remark): void
{
$this->remark = $remark;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午3:41
*/
namespace Lib\remote\api\message;
class FailMessage extends Message
{
/**
* @var string
*/
protected $templateId = '';
/**
* @var string
*/
private $first = '充电口打开失败,已取消订单,退款稍后送达,请注意查收哟';
/**
* @var string
*/
private $orderId = '';
/**
* @var string
*/
private $address = '';
/**
* @var int
*/
private $amount = 0;
/**
* @var string
*/
private $remark = '温馨提示:超时关闭此次交易,支付金额会在1个工作日内退回您的余额或零钱,请注意查看,若未收到请联系我们的客服为您处理。若为充电口异常,请您及时更换至其它充电口充电';
public function __construct()
{
$this->templateId = getenv('MESSAGE_FAIL');
}
public function getPushJson(): string
{
return json_encode([
'first' => [
'value' => $this->first,
'color' => '#333',
],
'keyword1' => [
'value' => sprintf('%012x', $this->orderId),
'color' => '#333',
],
'keyword2' => [
'value' => $this->address,
'color' => '#333',
],
'keyword3' => [
'value' => number_format($this->amount / 100.0, 2),
'color' => '#333',
],
'remark' => [
'value' => $this->remark,
'color' => '#333',
],
]);
}
/**
* @return string
*/
public function getFirst(): string
{
return $this->first;
}
/**
* @param string $first
*/
public function setFirst(string $first): void
{
$this->first = $first;
}
/**
* @return string
*/
public function getOrderId(): string
{
return $this->orderId;
}
/**
* @param string $orderId
*/
public function setOrderId(string $orderId): void
{
$this->orderId = $orderId;
}
/**
* @return string
*/
public function getAddress(): string
{
return $this->address;
}
/**
* @param string $address
*/
public function setAddress(string $address): void
{
$this->address = $address;
}
/**
* @return int
*/
public function getAmount(): int
{
return $this->amount;
}
/**
* @param int $amount
*/
public function setAmount(int $amount): void
{
$this->amount = $amount;
}
/**
* @return string
*/
public function getRemark(): string
{
return $this->remark;
}
/**
* @param string $remark
*/
public function setRemark(string $remark): void
{
$this->remark = $remark;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:27
*/
namespace Lib\remote\api\message;
abstract class Message
{
/**
* @var string
*/
protected $templateId;
/**
* @var string
*/
protected $orderId;
/**
* @var int
*/
protected $userId;
abstract public function getPushJson(): string;
/**
* @return mixed
*/
public function getTemplateId()
{
return $this->templateId;
}
/**
* @param mixed $templateId
*/
public function setTemplateId($templateId): void
{
$this->templateId = $templateId;
}
/**
* @return int
*/
public function getUserId(): int
{
return $this->userId;
}
/**
* @param int $userId
*/
public function setUserId(int $userId): void
{
$this->userId = $userId;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/18
* Time: 上午10:52
*/
namespace Lib\remote\api\message;
class PowerExceedMessage extends Message
{
/**
* @var array|false|string
*/
protected $templateId = '';
/**
* @var string
*/
private $first = '尊敬的用户,你的爱车功率过大,本次充电已结束';
/**
* @var string
*/
private $remark = '温馨提示:电瓶车的功率超出了充电口所允许的最大充电功率,您可以在公众号后台留言或直接拨打客服热线进行咨询';
/**
* @var string
*/
private $startTime = '';
/**
* @var string
*/
private $chargerTime = '';
/**
* @var string
*/
private $endTime = '';
/**
* PowerExceedMessage constructor.
*/
public function __construct() {
$this->templateId = getenv('MESSAGE_POWER_EXCEED');
}
public function getPushJson(): string
{
return json_encode([
'first' => [
'value' => $this->first,
'color' => '#333',
],
'keyword1' => [
'value' => $this->startTime,
'color' => '#333',
],
'keyword2' => [
'value' => $this->chargerTime.'分钟',
'color' => '#333',
],
'keyword3' => [
'value' => $this->endTime,
'color' => '#333',
],
'remark' => [
'value' => $this->remark,
'color' => '#333',
],
]);
}
/**
* @return array|false|string
*/
public function getTemplateId()
{
return $this->templateId;
}
/**
* @param array|false|string $templateId
*/
public function setTemplateId($templateId): void
{
$this->templateId = $templateId;
}
/**
* @return string
*/
public function getFirst(): string
{
return $this->first;
}
/**
* @param string $first
*/
public function setFirst(string $first): void
{
$this->first = $first;
}
/**
* @return string
*/
public function getRemark(): string
{
return $this->remark;
}
/**
* @param string $remark
*/
public function setRemark(string $remark): void
{
$this->remark = $remark;
}
/**
* @return string
*/
public function getStartTime(): string
{
return $this->startTime;
}
/**
* @param string $startTime
*/
public function setStartTime(string $startTime): void
{
$this->startTime = $startTime;
}
/**
* @return string
*/
public function getChargerTime(): string
{
return $this->chargerTime;
}
/**
* @param string $chargerTime
*/
public function setChargerTime(string $chargerTime): void
{
$this->chargerTime = $chargerTime;
}
/**
* @return string
*/
public function getEndTime(): string
{
return $this->endTime;
}
/**
* @param string $endTime
*/
public function setEndTime(string $endTime): void
{
$this->endTime = $endTime;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:35
*/
namespace Lib\remote\api\message;
use GuzzleHttp\Client;
use Lib\log\Log;
class SendMessage
{
private $uri = '';
private $path = '';
public function __construct()
{
$this->path = 'api/v1/wechatMessage';
$this->uri = getenv('MESSAGE_API_URL');
}
/**
* @param Message $message
* @return bool
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function request(Message $message)
{
$client = new Client([
'base_uri' => $this->uri,
'http_errors' => false,
]);
$response = $client->request('POST', $this->uri, [
'form_params' => [
'userId' => $message->getUserId(),
'templateId' => $message->getTemplateId(),
'data' => $message->getPushJson(),
],
]);
if ($response->getStatusCode() === 200) {
Log::debug('发送模版消息');
}
return $response->getStatusCode() === 200;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/8/17
* Time: 下午2:27
*/
namespace Lib\remote\api\message;
class StartMessage extends Message
{
/**
* @var string
*/
private $first = '充电已经开始,请注意接收消息';
/**
* @var string
*/
private $startTime = '';
/**
* @var string
*/
private $address = '';
/**
* @var string
*/
private $amount = '';
/**
* @var string
*/
private $remark = '感谢你的使用';
/**
* StartMessage constructor.
*/
public function __construct()
{
$this->templateId = getenv('MESSAGE_START');
}
/**
* @return string
*/
public function getPushJson(): string
{
$this->startTime = date('Y-m-d H:i:s');
return json_encode([
'first' => [
'value' => $this->first,
'color' => '#333',
],
'keyword1' => [
'value' => $this->startTime,
'color' => '#333',
],
'keyword2' => [
'value' => $this->address,
'color' => '#333',
],
'keyword3' => [
'value' => number_format($this->amount / 100, 2),
'color' => '#333',
],
'remark' => [
'value' => $this->remark . '\n' . "($this->orderId)",
'color' => '#333',
],
]);
// TODO: Implement getPushJson() method.
}
/**
* @return string
*/
public function getAddress(): string
{
return $this->address;
}
/**
* @param string $address
*/
public function setAddress(string $address): void
{
$this->address = $address;
}
/**
* @return string
*/
public function getAmount(): string
{
return $this->amount;
}
/**
* @param string $amount
*/
public function setAmount(string $amount): void
{
$this->amount = $amount;
}
/**
* @return string
*/
public function getRemark(): string
{
return $this->remark;
}
/**
* @param string $remark
*/
public function setRemark(string $remark): void
{
$this->remark = $remark;
}
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment