Commit f19d0929 by BANice

线上提交版

parent cf0bdc43
......@@ -10,6 +10,7 @@
<excludeFolder url="file://$MODULE_DIR$/vendor/illuminate/container" />
<excludeFolder url="file://$MODULE_DIR$/vendor/illuminate/contracts" />
<excludeFolder url="file://$MODULE_DIR$/vendor/illuminate/database" />
<excludeFolder url="file://$MODULE_DIR$/vendor/illuminate/events" />
<excludeFolder url="file://$MODULE_DIR$/vendor/illuminate/support" />
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
......
......@@ -19,6 +19,7 @@
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
<path value="$PROJECT_DIR$/vendor/psr/log" />
<path value="$PROJECT_DIR$/vendor/illuminate/events" />
</include_path>
</component>
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
......
<?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
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:24
*/
namespace Lib\cdz_order;
use Lib\cdz_order\state\State;
class Order
{
/**
* @var int
*/
private $id;
/**
* @var string
*/
private $outTradeNo;
/**
* @var string
*/
private $createdTime = '';
/**
* @var int
*/
private $userId;
/**
* @var int
*/
private $payAmount;
/**
* @var int
*/
private $purchaseTime;
/**
* @var int
*/
private $portId;
/**
* @var int
*/
private $gatewayId;
/**
* @var string
*/
private $gatewayMac;
/**
* @var int
*/
private $stationId;
/**
* @var int
*/
private $portLogicId;
/**
* @var State
*/
private $currentState;
/**
* @var int
*/
private $stateCode;
/**
* @var array
*/
private $orderCache;
/**
* @var string
*/
private $portName;
/**
* @var string
*/
private $stationName;
public function __get($name)
{
return $this->$name;
}
/**
* @param \Redis $redis
* @return array|bool
*/
public function getOrderCache(\Redis $redis)
{
if(isset($this->orderCache) === false){
$keyName = State::ORDER_HASH_PREFIX . $this->id;
if ($redis->exists($keyName) == false) {
return false;
}
$this->orderCache = $redis->hGetAll($keyName);
foreach ($this->orderCache as $key => $value) {
$this->$key = $value;
}
}
return $this->orderCache;
}
public function setOrderCache(\Redis $redis, $orderCache): void
{
$this->orderCache = $orderCache;
$redis->hMset(State::ORDER_HASH_PREFIX . $this->id, $orderCache);
}
/**
* @return State
*/
public function getCurrentState(): State
{
return $this->currentState;
}
/**
* @param State $currentState
*/
public function setCurrentState(State $currentState): void
{
$this->currentState = $currentState;
}
/**
* @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 $this->portLogicId;
}
/**
* @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 getStationId(): int
{
return $this->stationId;
}
/**
* @param int $stationId
*/
public function setStationId(int $stationId): void
{
$this->stationId = $stationId;
}
/**
* @return string
*/
public function getOutTradeNo(): string
{
return $this->outTradeNo;
}
/**
* @param string $outTradeNo
*/
public function setOutTradeNo(string $outTradeNo): void
{
$this->outTradeNo = $outTradeNo;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 下午6:22
*/
namespace Lib\cdz_order\adaptor;
use Lib\cdz_order\Order;
use Lib\redis\RedisSingle;
class UsingOrderAdaptor
{
private $order;
public function __construct(Order $order) {
$this->order = $order;
}
public function adaptor()
{
$orderCache = $this->order->getOrderCache(RedisSingle::getRedis());
return [
'port_id' => $orderCache['portId'],
'station_id' => $orderCache['stationId'],
'state' => $orderCache['stateCode'],
'order_id' => $orderCache['id'],
'charger_time' => $orderCache['purchaseTime'],
'created_at' => date('Y-m-d H:i:s',$orderCache['createdTime']),
'port_name' => $orderCache['portName'],
'order_amount' => number_format($orderCache['payAmount']/100,2),
'start_time' => isset($orderCache['startTime']) ? date('Y-m-d H:i:s',$orderCache['startTime']): null,
'end_time' => isset($orderCache['endTime']) ? date('Y-m-d H:i:s',$orderCache['endTime']) : null,
'shed_time' => isset($orderCache['shedTime']) ? date('Y-m-d H:i:s',$orderCache['shedTime']) : null,
'station_name' => $orderCache['stationName'],
];
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:34
*/
namespace Lib\cdz_order\order;
use Lib\cdz_order\Order;
use Lib\cdz_order\state\State;
class SaveOrder
{
protected $state;
protected $redis;
public function __construct(State $state)
{
$this->state = $state;
$this->redis = $state->getRedis();
}
public function saveCreatedTime()
{
$this->redis->hSet($this->state->getKeyName(), State::FIELD[0], $this->state->getOrder()->getCreatedTime());
}
public function saveStartTime()
{
$this->redis->hSet($this->state->getKeyName(), State::FIELD[2], $this->state->getStartTime());
}
public function saveShedTime()
{
$this->redis->hSet($this->state->getKeyName(), State::FIELD[4], $this->state->getShedTime());
}
public function savePortOfflineTime()
{
$this->redis->hSet($this->state->getKeyName(), State::FIELD[5], $this->state->getOfflineTime());
}
public function savePortOnlineTime()
{
$this->redis->hSet($this->state->getKeyName(), State::FIELD[6], $this->state->getOnlineTime());
}
public function saveStateCode()
{
$this->redis->hSet($this->state->getKeyName(), State::FIELD[7], $this->state->getOrder()->getStateCode());
}
public function pipe()
{
$this->state->getRedis()->multi(2);
}
public function exec()
{
$this->state->getRedis()->exec();
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:36
*/
namespace Lib\cdz_order\state;
use Lib\cdz_order\Order;
class Charger extends State
{
public function __construct(Order $order, \Redis $redis) { parent::__construct($order, $redis); }
public function toCharger()
{
// TODO: Implement toCharger() method.
}
public function toPortShed()
{
// TODO: Implement toPortShed() method.
}
public function toPowerExceed()
{
// TODO: Implement toPowerExceed() method.
}
public function toFull()
{
// TODO: Implement toFull() method.
}
public function toFinish()
{
// TODO: Implement toFinish() method.
}
public function toOffline()
{
// TODO: Implement toOffline() method.
}
public function toOnline()
{
// TODO: Implement toOnline() method.
}
public function toWaiting()
{
// TODO: Implement toWaiting() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午10:49
*/
namespace Lib\cdz_order\state;
use Lib\cdz_order\Order;
class Created extends State
{
/**
* Created constructor.
* @param Order $order
* @param \Redis $redis
* @throws \ReflectionException
*/
public function __construct(Order $order, \Redis $redis)
{
parent::__construct($order, $redis);
$reflection = new \ReflectionClass($order);
$properties = $reflection->getDefaultProperties();
$attributes = array_keys($properties);
foreach ($attributes as $attribute) {
$properties[$attribute] = $order->$attribute;
}
unset($properties['orderCache']);
$redis->hMset($this->keyName, $properties);
$redis->expire($this->keyName,60 * 60 * 24 * 2);
}
public function toCharger()
{
// TODO: Implement toCharger() method.
}
public function toPortShed()
{
// TODO: Implement toPortShed() method.
}
public function toPowerExceed()
{
// TODO: Implement toPowerExceed() method.
}
public function toFull()
{
// TODO: Implement toFull() method.
}
public function toFinish()
{
// TODO: Implement toFinish() method.
}
public function toOffline()
{
// TODO: Implement toOffline() method.
}
public function toOnline()
{
// TODO: Implement toOnline() method.
}
/**
* 创建的订单状态转变为等待充电
*/
public function toWaiting()
{
$this->order->setStateCode(-1);
$this->saveOrder->saveStateCode();
$this->order->setCurrentState(new WaitingCharger($this->order,$this->redis));
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:39
*/
namespace Lib\cdz_order\state;
class Finish
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午10:32
*/
namespace Lib\cdz_order\state;
use Lib\cdz_order\Order;
class Offline extends State
{
public function toWaiting()
{
// TODO: Implement toWaiting() method.
}
public function __construct(Order $order, \Redis $redis, int $offlineReason = 1)
{
parent::__construct($order, $redis);
$this->offlineReason = $offlineReason;
}
/**
*
*/
public function toCharger()
{
$purchaseTime = $this->order->getPurchaseTime();
$startTime = $this->getStartTime();
$offlineTime = $this->getOfflineTime();
$this->onlineTime = time();
if ($this->offlineReason == 1) {
$remainTime = $purchaseTime * 60 - ($offlineTime - $startTime);
$this->remainChargerTime = (int)ceil($remainTime / 60);
} else {
$remainTime = $purchaseTime * 60 - ($this->onlineTime - $startTime);
$this->remainChargerTime = $remainTime;
}
$this->saveOrder->savePortOnlineTime();
$this->order->setCurrentState(new Charger($this->order,$this->redis));
}
public function toPortShed()
{
// TODO: Implement toPortShed() method.
}
public function toPowerExceed()
{
// TODO: Implement toPowerExceed() method.
}
public function toFull()
{
// TODO: Implement toFull() method.
}
public function toFinish()
{
// TODO: Implement toFinish() method.
}
public function toOffline()
{
// TODO: Implement toOffline() method.
}
public function toOnline()
{
// TODO: Implement toOnline() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午10:32
*/
namespace Lib\cdz_order\state;
class Online extends State
{
public function toCharger()
{
// TODO: Implement toCharger() method.
}
public function toPortShed()
{
// TODO: Implement toPortShed() method.
}
public function toPowerExceed()
{
// TODO: Implement toPowerExceed() method.
}
public function toFull()
{
// TODO: Implement toFull() method.
}
public function toFinish()
{
// TODO: Implement toFinish() method.
}
public function toOffline()
{
// TODO: Implement toOffline() method.
}
public function toOnline()
{
// TODO: Implement toOnline() method.
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:36
*/
namespace Lib\cdz_order\state;
class PortShed
{
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:30
*/
namespace Lib\cdz_order\state;
use Lib\cdz_order\Order;
use Lib\cdz_order\order\SaveOrder;
abstract class State
{
/**
* 订单状态包含的参数
*/
const FIELD = [
'createdTime',
'purchaseTime',
'startTime',
'finishTime',
'shedTime',
'offlineTime',
'onlineTime',
'stateCode',
];
/**
* 订单状态hash前缀
*/
const ORDER_HASH_PREFIX = 'cdz:order:state:';
/**
* @var Order
*/
protected $order;
/**
* @var SaveOrder
*/
protected $saveOrder;
/**
* @var string
*/
protected $keyName = '';
/**
* @var \Redis
*/
protected $redis;
/**
* @var string
*/
protected $shedTime;
/**
* @var string
*/
protected $startTime;
/**
* @var string
*/
protected $endTime;
/**
* @var string
*/
protected $offlineTime;
/**
* @var string
*/
protected $onlineTime;
/**
* @var int
*/
protected $offlineReason;
/**
* @var int
*/
protected $remainChargerTime;
/**
* State constructor.
* @param Order $order
* @param \Redis $redis
*/
public function __construct(Order $order, \Redis $redis)
{
$this->order = $order;
$this->redis = $redis;
$this->keyName = self::ORDER_HASH_PREFIX . $order->getId();
$this->saveOrder = new SaveOrder($this);
$orderCache = $order->getOrderCache($redis);
if (is_array($orderCache)) {
foreach ($orderCache as $key => $value) {
if (isset($value) === true) {
if (property_exists($this, $key) === true) {
$this->$key = $value;
}
}
}
}
}
abstract public function toCharger();
abstract public function toPortShed();
abstract public function toPowerExceed();
abstract public function toFull();
abstract public function toFinish();
abstract public function toOffline();
abstract public function toOnline();
abstract public function toWaiting();
/**
* @return Order
*/
public function getOrder(): Order
{
return $this->order;
}
/**
* @param Order $order
*/
public function setOrder(Order $order): void
{
$this->order = $order;
}
/**
* @return SaveOrder
*/
public function getSaveOrder(): SaveOrder
{
return $this->saveOrder;
}
/**
* @param SaveOrder $saveOrder
*/
public function setSaveOrder(SaveOrder $saveOrder): void
{
$this->saveOrder = $saveOrder;
}
/**
* @return string
*/
public function getKeyName(): string
{
return $this->keyName;
}
/**
* @param string $keyName
*/
public function setKeyName(string $keyName): void
{
$this->keyName = $keyName;
}
/**
* @return \Redis
*/
public function getRedis(): \Redis
{
return $this->redis;
}
/**
* @param \Redis $redis
*/
public function setRedis(\Redis $redis): void
{
$this->redis = $redis;
}
/**
* @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;
}
/**
* @return int
*/
public function getOfflineReason(): int
{
return $this->offlineReason;
}
/**
* @param int $offlineReason
*/
public function setOfflineReason(int $offlineReason): void
{
$this->offlineReason = $offlineReason;
}
/**
* @return int
*/
public function getRemainChargerTime(): int
{
return $this->remainChargerTime;
}
/**
* @param int $remainChargerTime
*/
public function setRemainChargerTime(int $remainChargerTime): void
{
$this->remainChargerTime = $remainChargerTime;
}
/**
* @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;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/16
* Time: 上午9:36
*/
namespace Lib\cdz_order\state;
use Lib\cdz_order\Order;
class WaitingCharger extends State
{
public function __construct(Order $order, \Redis $redis) { parent::__construct($order, $redis); }
public function toWaiting()
{
// TODO: Implement toWaiting() method.
}
/**
* 订单从等待充电转为开始充电状态
*/
public function toCharger(): void
{
$this->setStartTime(time());
$this->order->setStateCode(12);
$this->order->setCurrentState(new Charger($this->order, $this->redis));
$this->saveOrder->pipe();
$this->saveOrder->saveStartTime();
$this->saveOrder->saveStateCode();
$this->saveOrder->exec();
$this->order->setCurrentState(new Charger($this->order, $this->redis));
}
/**
* @throws \Exception
*/
public function toPortShed()
{
throw new \Exception(' waiting state can not change to port shed');
// TODO: Implement toPortShed() method.
}
/**
* @throws \Exception
*/
public function toPowerExceed()
{
throw new \Exception('waiting state can not change to power exceed');
// TODO: Implement toPowerExceed() method.
}
/**
* @throws \Exception
*/
public function toFull()
{
throw new \Exception('waiting state can not change to full state');
// TODO: Implement toFull() method.
}
public function toFinish()
{
// TODO: Implement toFinish() method.
}
/**
* 充电中口子发生离线,订单状态变为离线
*/
public function toOffline()
{
$this->offlineTime = time();
$this->saveOrder->savePortOfflineTime();
$this->order->setCurrentState(new Offline($this->order, $this->redis));
}
/**
* @throws \Exception
*/
public function toOnline()
{
throw new \Exception('waiting state can not change to online');
// TODO: Implement toOnline() method.
}
public function toChangePort(int $portId, string $portName,int $lastPortId,int $logicNum)
{
$this->order->setPortId($portId);
$this->order->setPortName($portName);
$this->redis->multi(2);
$this->redis->hMset($this->keyName, ['portId' => $portId, 'portName' => $portName,'portLogicId' => $logicNum]);
$this->redis->hDel('port:using_order_id',$lastPortId);
$this->redis->hSet('port:using_order_id',$portId,$this->order->getId());
$this->redis->zDelete('port:using_user_id',$lastPortId);
$this->redis->zAdd('port:using_user_id',$this->order->getUserId(),$portId);
$this->redis->exec();
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/10
* Time: 上午10:57
*/
namespace Lib\order_exception;
class Exception
{
const STATE_MESSAGE = [
'12' => '开始充电',
'10' => '口子离线',
'11' => '口子上线',
'13' => '开始充电失败(异常)',
'14' => '插口脱落',
'30' => '充电计时结束',
'31' => '远程关闭',
'32' => '插口脱落结束充电',
'34' => '功率超限结束充电',
'99' => '下发开始充电命令',
'98' => '更换充电口',
'97' => '下发结束充电命令',
'96' => '插口脱落超过10分钟,结束充电',
'95' => '3分钟未插上插头,结束充电并退款',
];
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/7/10
* Time: 上午11:09
*/
namespace Lib\order_exception;
use Lib\Log;
use Illuminate\Database\Capsule\Manager as Capsule;
class OrderTrace
{
/**
* @var string
*/
private $orderId ='';
/**
* @var string
*/
private $state = '';
/**
* @var array
*/
private $data = [];
/**
* OrderTrace constructor.
* @param string $state
*/
public function __construct($state = '') {
$this->state = $state;
}
/**
* @return string
*/
public function getOrderId(): string
{
return $this->orderId;
}
/**
* @param string $orderId
*/
public function setOrderId(string $orderId): void
{
$this->orderId = $orderId;
}
/**
* 按照state记录订单异常
*/
public function writeTrace()
{
if (!isset(Exception::STATE_MESSAGE[$this->state]))
{
Log::error('记录订单异常无次state'."($this->state)");
return ;
}
try{
$date = date('Y-m-d H:i:s');
Capsule::table('wx_charger_orders_exception')->insert([
'state' => $this->state,
'desc' => Exception::STATE_MESSAGE[$this->state],
'data' => json_encode($this->data),
'created_at' => $date,
'updated_at' => $date,
'order_id' => $this->orderId,
]);
}catch (\Exception $exception)
{
Log::error($exception->getMessage());
}
}
/**
* 记录订单异常
* @param int $state
* @param string $message
*/
public function writeRawTrace(int $state,string $message)
{
try{
$date = date('Y-m-d H:i:s');
Capsule::table('wx_charger_orders_exception')->insert([
'state' => $this->state,
'desc' => $message,
'data' => json_encode($this->data),
'created_at' => $date,
'updated_at' => $date,
'order_id' => $this->orderId,
]);
}catch (\Exception $exception)
{
Log::error($exception->getMessage());
}
}
/**
* @return array
*/
public function getData(): array
{
return $this->data;
}
/**
* @param array $data
*/
public function setData(array $data): void
{
$this->data = $data;
}
}
<?php
/**
* Created by PhpStorm.
* User: suhangyang
* Date: 2018/5/7
* Time: 下午4:55
*/
namespace Lib\redis;
use Illuminate\Support\Facades\Redis;
use Log;
class MyRedis
{
/**
* @var \Redis
*/
private $redis;
/**
* @var \Redis
*/
private $pipe;
/**
* @var bool
*/
private $isUsePipe = false;
public function __construct()
{
try {
$this->redis = new \Redis();
$this->redis->connect(env('REDIS_HOST'), 6379);
$this->redis->select(4);
} catch (\RedisException $exception) {
Log::error($exception->getMessage());
}
}
/**
* @return \Redis
*/
public function getRedis(): \Redis
{
return $this->redis;
}
/**
* @param \Redis $redis
*/
public function setRedis(\Redis $redis)
{
$this->redis = $redis;
}
public function getGatewayMacById($id)
{
if ($this->isUsePipe === true) {
return $this->pipe->hGet(RedisKey::GATEWAY_ID_MAC_HASH, $id);
}
return $this->redis->hGet(RedisKey::GATEWAY_ID_MAC_HASH, $id);
}
public function getPortLogicByMac($mac)
{
if ($this->isUsePipe === true) {
return $this->pipe->hGet(RedisKey::GATEWAY_PORT_MAC_LOGIC_ONEHASH, $mac);
}
return $this->redis->hGet(RedisKey::GATEWAY_PORT_MAC_LOGIC_ONEHASH, $mac);
}
public function getPortMacById($id)
{
if ($this->isUsePipe === true) {
return $this->pipe->hGet(RedisKey::GATEWAY_PORT_ID_MAC_HASH, $id);
}
return $this->redis->hGet(RedisKey::GATEWAY_PORT_ID_MAC_HASH, $id);
}
public function pipe()
{
$this->pipe = $this->redis->multi(\Redis::PIPELINE);
$this->isUsePipe = true;
return $this->redis;
}
/**
* @return array
*/
public function exec()
{
return $this->pipe->exec();
}
/**
* @return \Redis
*/
public function getPipe(): \Redis
{
return $this->pipe;
}
/**
* @param \Redis $pipe
*/
public function setPipe(\Redis $pipe)
{
$this->pipe = $pipe;
}
/**
* @return bool
*/
public function isUsePipe(): bool
{
return $this->isUsePipe;
}
/**
* @param bool $isUsePipe
*/
public function setIsUsePipe(bool $isUsePipe)
{
$this->isUsePipe = $isUsePipe;
}
}
<?php
/**
* Created by PhpStorm.
* User: suhangyang
* Date: 2018/5/11
* Time: 上午9:12
*/
namespace Lib\redis;
class RedisKey
{
const GATEWAY_PREFIX = 'cdz:gateway:';
const GATEWAY_PORT_LOGIC_MAC_HASH = ':port:logic_mac:hash';
const GATEWAY_PORT_MAC_LOGIC_HASH = ':port:mac_logic:hash';
const GATEWAY_PORT_MAC_LOGIC_ONEHASH = 'cdz:gateway:port_logic:hash';
const GATEWAY_PORT_ID_MAC_HASH = 'cdz:gateway:port:id_info:hash';
const GATEWAY_PORT_ID_LOGIC_HASH = 'cdz:gateway:port:id_logic:hash';
/**
* 网关
*/
const PORT_MAC_HASH = 'cdz:gateway:port:mac_logic_map:hash';
/**
* fixme
*/
const GATEWAY_PORT_HASH = 'cdz:gateway:port:hash';
/**
* 网关id映射mac地址hash
*/
const GATEWAY_ID_MAC_HASH = 'cdz:gateway:id_mac:hash';
/**
* 网关mac地址映射idhash
*/
const GATEWAY_MAC_ID_HASH = 'cdz:gateway:mac_id:hash';
/**
* 网关信息
*/
const GATEWAY_INFO = 'cdz:gateway:info:hash';
/**
* 口子状态zset
*/
const PORT_STATE = 'port:id_state:zset';
const GATEWAY_PORT_STATE = 'gateway:port:state:';
const STATION_PORT_STATE = 'station:port:state:';
const WX_USER_ID_OPENID_HASH ='cdz:wx_users:id_openid:hash';
const PORT_USING_ORDER_ID = 'port:using_order_id';
const PORT_USING_USER_ID = 'port:using_user_id';
const ORDER_STATE = 'cdz:order:state:zset';
/**
* 获取网关对应的口子的逻辑地址mac地址的hash KEY
* @param string $gatewayMac
* @return string
*/
public static function getGatewayPortLogicHashKey(string $gatewayMac)
{
return self::GATEWAY_PREFIX.$gatewayMac.self::GATEWAY_PORT_LOGIC_MAC_HASH;
}
public static function getGatewayPortMacHashKey(string $gatewayMac)
{
return self::GATEWAY_PREFIX.$gatewayMac.self::GATEWAY_PORT_MAC_LOGIC_HASH;
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: suhangyang
* Date: 2018/5/15
* Time: 上午10:38
*/
namespace Lib\redis;
class RedisSingle
{
/**
* @var \Redis
*/
private static $redis = null;
/**
* @return \Redis
*/
public static function getRedis() : \Redis
{
if(is_null(static::$redis))
{
static::instance();
}
return static::$redis;
}
/**
* @return \Redis
*/
public static function instance()
{
if (is_null(static::$redis)) {
static::$redis = new \Redis();
static::$redis->connect('redis.test.senthink.com');
static::$redis->select(4);
}
return static::$redis;
}
public static function __callStatic($name, $arguments)
{
static::instance();
return call_user_func_array([static::$redis, $name], $arguments);
}
public static function pipe()
{
static::instance();
static::$redis = static::$redis->multi(2);
}
/**
* @return array
*/
public static function exec()
{
static::instance();
return static::$redis->exec();
}
}
\ No newline at end of file
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/5/31
* Time: 上午11:22
*/
namespace Lib\redis\user;
use Lib\balance\BalanceOrder;
use Lib\BaseOrder;
use Lib\redis\RedisSingle;
use Lib\wx\pay_notify\order\ChargerOrder;
use Lib\wx\pay_notify\order\ChargerOrderTime;
use Log;
class UserUsingOrder
{
const USER_USING_ORDERS = 'user:using:orders:';
const USER_USING_PORTS = 'port:using_user_id';
const ORDER_USING_PORTS = 'port:using_order_id';
/**
* @var \Redis
*/
private $redis;
/**
* @var int
*/
private $userId;
public function __construct()
{
$this->redis = RedisSingle::getRedis();
}
/**
* 添加用户正在使用的订单id
* @param \Redis $redis
* @param BaseOrder $baseOrder
*/
public function addUsingWxOrder(\Redis $redis, BaseOrder $baseOrder)
{
$this->redis = $redis;
if ($baseOrder instanceof ChargerOrderTime) {
$this->redis->hSet(self::ORDER_USING_PORTS, $baseOrder->getPort()->getPortId(), $baseOrder->getOrderId());
}
}
public function addUsingBalanceOrder(\Redis $redis, BalanceOrder $balanceOrder)
{
$this->redis = $redis;
$this->redis->hSet(self::ORDER_USING_PORTS,$balanceOrder->getPort()->getPortId(),$balanceOrder->getOrderId());
}
/**
* 更新端口正在使用的用户id
* @param int $portId
* @param int $userId
*/
public function setPortUsingUserId(int $portId, int $userId)
{
$this->redis->zAdd(self::USER_USING_PORTS, $userId, $portId);
}
/**
* 返回当前用户正在使用的端口号
* @return array
*/
public function getUserUsingPortId() : array
{
return $this->redis->zRangeByScore('port:using_user_id', $this->userId, $this->userId);
}
/**
* 获取端口正在使用的订单id
* @param $portId
* @return string
*/
public function getPortOrderId($portId)
{
return $this->redis->hGet(self::ORDER_USING_PORTS, $portId);
}
/**
* 获取端口正在使用的订单ids
* @param array $portsId
* @return array
*/
public function getPortsOrderId(array $portsId)
{
return $this->redis->hMGet(self::ORDER_USING_PORTS, $portsId);
}
/**
* @return int
*/
public function getUserId(): int
{
return $this->userId;
}
/**
* @param int $userId
*/
public function setUserId(int $userId): void
{
$this->userId = $userId;
}
/**
* @return \Redis
*/
public function getRedis(): \Redis
{
return $this->redis;
}
/**
* @param \Redis $redis
*/
public function setRedis(\Redis $redis): void
{
$this->redis = $redis;
}
}
<?php
/**
* Created by PhpStorm.
* User: banice
* Date: 2018/5/31
* Time: 上午11:22
*/
namespace Lib\redis\user;
use Lib\balance\BalanceOrder;
use Lib\wx\pay_notify\order\ChargerOrder;
use Lib\wx\pay_notify\order\ChargerOrderTime;
class UserUsingPort
{
const USER_USING_ORDERS = 'user:orders:using:';
public function addUsingWxOrder(\Redis $redis, ChargerOrder $chargerOrder)
{
$userId = $chargerOrder->getUserId();
$key = self::USER_USING_ORDERS.$userId;
if($chargerOrder instanceof ChargerOrderTime)
{
$chargerTime = $chargerOrder->getChargerTime();
$orderId = $chargerOrder->getOrderId();
$redis->hSet($key,$orderId,json_encode([
'time' => $chargerTime,
]));
$ttl = $redis->ttl($key);
if($chargerTime * 60 > $ttl)
{
$redis->expire($key,$chargerTime * 60);
}
}
}
public function addUsingBalanceOrder(\Redis $redis,BalanceOrder $balanceOrder)
{
}
}
\ No newline at end of file
......@@ -92,13 +92,8 @@ class Send
$message = $this->makeMessage();
//debug
if (Gateway::isUidOnline($clientUid) === 1) {
var_dump(['send_message' => $message,'time' => date('Y-m-d H:i:s')]);
Gateway::sendToUid($clientUid, $message);
$result = true;
......
......@@ -31,21 +31,28 @@ class StopChargerCommand extends Command
*/
private $gatewayMac;
/**
* @var int
*/
private $stopType = 41;
/**
* @var string
*/
protected $headerCtrl = '05';
public function getMessageBody(): string
{
$logicNum = sprintf('%02x',$this->logicNum);
$logicNum = sprintf('%02x', $this->logicNum);
$orderId = sprintf('%012x', $this->orderId);
$orderId = sprintf('%012x',$this->orderId);
$stopType = sprintf('%02x', $this->stopType);
return $this->messageBody = $logicNum.$orderId;
return $this->messageBody = $logicNum . $orderId . $stopType;
}
......@@ -125,6 +132,46 @@ class StopChargerCommand extends Command
$this->headerCtrl = $headerCtrl;
}
/**
* @return int
*/
public function getStopType(): int
{
return $this->stopType;
}
/**
* @param int $stopType
*/
public function setStopType(int $stopType): void
{
$this->stopType = $stopType;
}
/**
* @param string $messageBody
*/
public function setMessageBody(string $messageBody): void
{
$this->messageBody = $messageBody;
}
/**
* @param string $clientId
*/
public function setClientId(string $clientId): void
{
$this->clientId = $clientId;
}
/**
* @param string $clientUid
*/
public function setClientUid(string $clientUid): void
{
$this->clientUid = $clientUid;
}
......
......@@ -11,6 +11,7 @@
"require": {
"illuminate/database": "^5.6",
"guzzlehttp/guzzle": "^6.3",
"monolog/monolog": "^1.23"
"monolog/monolog": "^1.23",
"illuminate/events": "^5.6"
}
}
......@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "964b5da01090400ae6a459d42bd37b10",
"content-hash": "47c9d4401aacfaf3641ef449fa2ecf37",
"packages": [
{
"name": "doctrine/inflector",
......@@ -402,6 +402,51 @@
"time": "2018-05-21T14:36:25+00:00"
},
{
"name": "illuminate/events",
"version": "v5.6.27",
"source": {
"type": "git",
"url": "https://github.com/illuminate/events.git",
"reference": "b6e73ed40478cef2ef98d5ddb27f333291606cea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/events/zipball/b6e73ed40478cef2ef98d5ddb27f333291606cea",
"reference": "b6e73ed40478cef2ef98d5ddb27f333291606cea",
"shasum": ""
},
"require": {
"illuminate/container": "5.6.*",
"illuminate/contracts": "5.6.*",
"illuminate/support": "5.6.*",
"php": "^7.1.3"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Illuminate\\Events\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Events package.",
"homepage": "https://laravel.com",
"time": "2018-02-26T19:00:55+00:00"
},
{
"name": "illuminate/support",
"version": "v5.6.23",
"source": {
......
......@@ -11,8 +11,11 @@ use Lib\rabbit_mq\MyRabbitMq;
use Lib\send\command\StopChargerCommand;
use Lib\Log;
use Lib\send\Send;
use Lib\api\message\ChargerTimeoutMessage;
use Lib\api\message\Push;
use Illuminate\Database\Capsule\Manager as Capsule;
use Illuminate\Events\Dispatcher;
use Illuminate\Container\Container;
use Lib\cdz_order\Order;
use Lib\redis\RedisSingle;
try {
$rabbitMq = new MyRabbitMq();
......@@ -46,75 +49,61 @@ try {
} catch (AMQPConnectionException $e) {
}
Log::info('启动消费者');
Log::info('启动检查口子脱落消费者');
try {
$queue->consume(function (AMQPEnvelope $envelope, AMQPQueue $queue) {
$dsn = 'mysql:dbname=cdzpay;host=db.test.senthink.com';
$user = 'cdz';
$password = 'senthink123';
$capule = new Capsule();
try {
$dbh = new PDO($dsn, $user, $password, [
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
]);
$capule->addConnection([
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
'driver' => 'mysql',
'host' => 'db.test.senthink.com',
'database' => 'cdzpay',
'username' => 'cdz',
'password' => 'senthink123',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
]);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$data = json_decode($envelope->getBody(), true);
Log::debug('body',$data);
$orderId = $data['order_id'];
$capule->setEventDispatcher(new Dispatcher(new Container()));
$orderInfo = $dbh->query('SELECT is_stop,port_id,created_at,charger_time,wx_user_id FROM wx_charger_orders WHERE id = ' . $orderId);
$capule->setAsGlobal();
$orderInfo = $orderInfo->fetch();
$capule->bootEloquent();
//todo 查询口子状态是否为插口脱落,是则下发结束充电命令。
if(isset($orderInfo['port_id'])) {
try {
$redis = new \Redis();
$redis->pconnect('redis.test.senthink.com', 6379, 1);
$data = json_decode($envelope->getBody(), true);
$redis->select(4);
if (isset($data['order_id']) === false) {
$queue->ack($envelope->getDeliveryTag());
$portId = $orderInfo['port_id'];
return;
$redis->multi(2);
$redis->zScore('port:id_state:zset',$portId);
}
$orderId = $data['order_id'];
$redis->hGet('port:id_logic:hash',$portId);
$shedTime = $data['shed_time'];
$result = $redis->exec();
$portState = $result[0];
$order = new Order();
$order->setId($orderId);
$logicNum = $result['1'];
$orderCache = $order->getOrderCache(RedisSingle::getRedis());
if(!isset($logicNum))
{
Log::error('逻辑地址未找到');
if ($orderCache === false) {
$queue->ack($envelope->getDeliveryTag());
return ;
return;
}
}
if($portState == 14)
{
if (isset($orderCache['shedTime'])) {
if ($shedTime == $orderCache['shedTime']) {
if ($order->getStateCode() == 14) {
$gatewayMac = $data['gateway_mac'];
$stopCommand = new StopChargerCommand();
......@@ -123,45 +112,38 @@ try {
$stopCommand->setGatewayMac($gatewayMac);
$stopCommand->setLogicNum($logicNum);
$stopCommand->setStopType(42);
$stopCommand->setLogicNum($order->getPortLogicId());
$send = new Send($stopCommand);
$stopCommand->setClientUid($gatewayMac);
$send = new Send($stopCommand);
if ($send->send() === false) {
Log::debug('结束订单命令发送失败');
Log::debug('结束订单命令发送失败(插口脱落十分钟)');
}else{
Log::debug('发送结束充电命令'.$orderId);
} else {
}
Log::debug('发送结束充电命令', ['order_id' => $orderId, 'desc' => '插口脱落十分钟']);
$chargerTimeoutMessage = new ChargerTimeoutMessage();
$chargerTimeoutMessage->setStartTime($orderInfo['created_at']);
}
$chargerTimeoutMessage->setChargerTime($orderInfo['charger_time']);
$orderTrace = new \Lib\order_exception\OrderTrace(96);
$chargerTimeoutMessage->setFirst(date('Y-m-d H:i:s'));
$orderTrace->setOrderId($orderId);
$push = new Push();
$orderTrace->writeTrace();
$push->push($chargerTimeoutMessage,$orderInfo['wx_user_id']);
}
} catch (Exception $exception) {
Log::error($exception->getMessage());
}
}
$queue->ack($envelope->getDeliveryTag());
......
......@@ -7,8 +7,8 @@ $baseDir = dirname($vendorDir);
return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
'72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
);
......@@ -15,6 +15,7 @@ return array(
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Lib\\' => array($baseDir . '/Lib'),
'Illuminate\\Support\\' => array($vendorDir . '/illuminate/support'),
'Illuminate\\Events\\' => array($vendorDir . '/illuminate/events'),
'Illuminate\\Database\\' => array($vendorDir . '/illuminate/database'),
'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
'Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'),
......
......@@ -8,9 +8,9 @@ class ComposerStaticInit8c119b004aa624b54e5609ed67b0bb28
{
public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
'72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
);
......@@ -38,6 +38,7 @@ class ComposerStaticInit8c119b004aa624b54e5609ed67b0bb28
'I' =>
array (
'Illuminate\\Support\\' => 19,
'Illuminate\\Events\\' => 18,
'Illuminate\\Database\\' => 20,
'Illuminate\\Contracts\\' => 21,
'Illuminate\\Container\\' => 21,
......@@ -91,6 +92,10 @@ class ComposerStaticInit8c119b004aa624b54e5609ed67b0bb28
array (
0 => __DIR__ . '/..' . '/illuminate/support',
),
'Illuminate\\Events\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/events',
),
'Illuminate\\Database\\' =>
array (
0 => __DIR__ . '/..' . '/illuminate/database',
......
......@@ -409,6 +409,53 @@
]
},
{
"name": "illuminate/events",
"version": "v5.6.27",
"version_normalized": "5.6.27.0",
"source": {
"type": "git",
"url": "https://github.com/illuminate/events.git",
"reference": "b6e73ed40478cef2ef98d5ddb27f333291606cea"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/illuminate/events/zipball/b6e73ed40478cef2ef98d5ddb27f333291606cea",
"reference": "b6e73ed40478cef2ef98d5ddb27f333291606cea",
"shasum": ""
},
"require": {
"illuminate/container": "5.6.*",
"illuminate/contracts": "5.6.*",
"illuminate/support": "5.6.*",
"php": "^7.1.3"
},
"time": "2018-02-26T19:00:55+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Illuminate\\Events\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "The Illuminate Events package.",
"homepage": "https://laravel.com"
},
{
"name": "illuminate/support",
"version": "v5.6.23",
"version_normalized": "5.6.23.0",
......
<?php
namespace Illuminate\Events;
use Illuminate\Container\Container;
use Illuminate\Contracts\Queue\Job;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class CallQueuedListener implements ShouldQueue
{
use InteractsWithQueue;
/**
* The listener class name.
*
* @var string
*/
public $class;
/**
* The listener method.
*
* @var string
*/
public $method;
/**
* The data to be passed to the listener.
*
* @var array
*/
public $data;
/**
* The number of times the job may be attempted.
*
* @var int
*/
public $tries;
/**
* The timestamp indicating when the job should timeout.
*
* @var int
*/
public $timeoutAt;
/**
* The number of seconds the job can run before timing out.
*
* @var int
*/
public $timeout;
/**
* Create a new job instance.
*
* @param string $class
* @param string $method
* @param array $data
* @return void
*/
public function __construct($class, $method, $data)
{
$this->data = $data;
$this->class = $class;
$this->method = $method;
}
/**
* Handle the queued job.
*
* @param \Illuminate\Container\Container $container
* @return void
*/
public function handle(Container $container)
{
$this->prepareData();
$handler = $this->setJobInstanceIfNecessary(
$this->job, $container->make($this->class)
);
call_user_func_array(
[$handler, $this->method], $this->data
);
}
/**
* Set the job instance of the given class if necessary.
*
* @param \Illuminate\Contracts\Queue\Job $job
* @param mixed $instance
* @return mixed
*/
protected function setJobInstanceIfNecessary(Job $job, $instance)
{
if (in_array(InteractsWithQueue::class, class_uses_recursive(get_class($instance)))) {
$instance->setJob($job);
}
return $instance;
}
/**
* Call the failed method on the job instance.
*
* The event instance and the exception will be passed.
*
* @param \Exception $e
* @return void
*/
public function failed($e)
{
$this->prepareData();
$handler = Container::getInstance()->make($this->class);
$parameters = array_merge($this->data, [$e]);
if (method_exists($handler, 'failed')) {
call_user_func_array([$handler, 'failed'], $parameters);
}
}
/**
* Unserialize the data if needed.
*
* @return void
*/
protected function prepareData()
{
if (is_string($this->data)) {
$this->data = unserialize($this->data);
}
}
/**
* Get the display name for the queued job.
*
* @return string
*/
public function displayName()
{
return $this->class;
}
/**
* Prepare the instance for cloning.
*
* @return void
*/
public function __clone()
{
$this->data = array_map(function ($data) {
return is_object($data) ? clone $data : $data;
}, $this->data);
}
}
<?php
namespace Illuminate\Events;
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Queue\Factory as QueueFactoryContract;
class EventServiceProvider extends ServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('events', function ($app) {
return (new Dispatcher($app))->setQueueResolver(function () use ($app) {
return $app->make(QueueFactoryContract::class);
});
});
}
}
{
"name": "illuminate/events",
"description": "The Illuminate Events package.",
"license": "MIT",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"require": {
"php": "^7.1.3",
"illuminate/container": "5.6.*",
"illuminate/contracts": "5.6.*",
"illuminate/support": "5.6.*"
},
"autoload": {
"psr-4": {
"Illuminate\\Events\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}
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