作者 竞泽

add all

  1 +{
  2 + "name": "lackoxygen/top-warehouse",
  3 + "type": "library",
  4 + "description": "e仓",
  5 + "license": "MIT",
  6 + "authors": [
  7 + {
  8 + "name": "jz",
  9 + "email": "jingzeou@outlook.com"
  10 + }
  11 + ],
  12 + "require": {
  13 + "php": ">=7.1"
  14 + },
  15 + "require-dev": {
  16 + "phpunit/phpunit": "~4.0"
  17 + },
  18 + "autoload": {
  19 + "psr-4": {
  20 + "lackoxygen\\TopWarehouse\\": "/src/"
  21 + }
  22 + }
  23 +}
  1 +<?php
  2 +
  3 +return [
  4 + 'appKey' => '1000370173100021',
  5 + 'appSecret' => 'dOsDS9ycaIWyD+4jKywnRw==',
  6 + 'url' => 'http://ews-test.topgoods.mobi',
  7 + 'options' => [
  8 + 'client' => [
  9 + 'time' => 60,
  10 + 'retry' => 0
  11 + ]
  12 + ]
  13 +];
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse;
  5 +
  6 +use GuzzleHttp\Exception\BadResponseException;
  7 +use GuzzleHttp\Exception\RequestException;
  8 +use GuzzleHttp\RequestOptions;
  9 +use Illuminate\Support\Arr;
  10 +use lackoxygen\TopWarehouse\Contracts\ClientInterface;
  11 +use lackoxygen\TopWarehouse\Contracts\RequestInterface;
  12 +use GuzzleHttp\Client as guzzleClient;
  13 +use lackoxygen\TopWarehouse\Contracts\ResponseInterface;
  14 +use lackoxygen\TopWarehouse\Exception\Exception;
  15 +use lackoxygen\TopWarehouse\Utils\SignatureUtil;
  16 +
  17 +class Client implements ClientInterface
  18 +{
  19 + protected $request;
  20 +
  21 + protected $guzzleClient;
  22 +
  23 + protected $config;
  24 +
  25 + protected function __construct(RequestInterface $request)
  26 + {
  27 + $this->request = $request();
  28 +
  29 + //$this->config = config(TopWarehouseServiceProvider::CONFIG_NAME);
  30 +
  31 + $this->config = [
  32 + 'app_key' => '1000370173100021',
  33 + 'app_secret' => 'dOsDS9ycaIWyD+4jKywnRw==',
  34 + 'options' => [
  35 + 'client' => [
  36 + 'base_uri' => 'http://ews-test.topgoods.mobi',
  37 + 'time' => 10,
  38 + ],
  39 + 'retry' => 1
  40 + ]
  41 + ];
  42 +
  43 + $clientOption = \Arr::get($this->config, 'options.client', []);
  44 +
  45 + $this->guzzleClient = new guzzleClient($clientOption);
  46 + }
  47 +
  48 + /**
  49 + * @param RequestInterface $request
  50 + *
  51 + * @return ClientInterface
  52 + */
  53 + public static function make(RequestInterface $request): ClientInterface
  54 + {
  55 + return new static($request);
  56 + }
  57 +
  58 + /**
  59 + * @return ResponseInterface
  60 + * @throws Exception
  61 + */
  62 + public function send(): ResponseInterface
  63 + {
  64 + $retry = Arr::get($this->config, 'options.retry', 1);
  65 +
  66 + try {
  67 + return retry($retry, function ($attempt) {
  68 + return $this->execute($attempt);
  69 + }, 100, function ($exception) {
  70 + return $exception instanceof RequestException || $exception instanceof BadResponseException;
  71 + });
  72 + } catch (\Throwable $exception) {
  73 + throw new Exception($exception);
  74 + }
  75 + }
  76 +
  77 +
  78 + /**
  79 + * @param $attempt
  80 + *
  81 + * @return ResponseInterface
  82 + * @throws \GuzzleHttp\Exception\GuzzleException
  83 + */
  84 + protected function execute($attempt): ResponseInterface
  85 + {
  86 + $key = RequestOptions::QUERY;
  87 + if ('GET' === strtoupper($this->request->getMethod())) {
  88 + $key = RequestOptions::QUERY;
  89 + } elseif ('POST' === strtoupper($this->request->getMethod())) {
  90 + if ($this->request->getContentType() === 'application/json') {
  91 + $key = RequestOptions::JSON;
  92 + } else {
  93 + $key = RequestOptions::FORM_PARAMS;
  94 + }
  95 + }
  96 + $data = $this->request->toArray() + [
  97 + 'app_key' => Arr::get($this->config, 'app_key'),
  98 + 'v' => $this->request->getVersion(),
  99 + 'timestamp' => date('Y-m-d H:i:s'),
  100 + ];
  101 +
  102 + $data['sign'] = SignatureUtil::generate($data, Arr::get($this->config, 'app_secret'));
  103 +
  104 + $response = $this->guzzleClient->request($this->request->getMethod(), $this->request->getPath(), [
  105 + $key => $data
  106 + ]);
  107 +
  108 + return new Response($response);
  109 + }
  110 +}
  1 +<?php
  2 +
  3 +namespace lackoxygen\TopWarehouse\Console;
  4 +
  5 +use Illuminate\Console\Command;
  6 +
  7 +class SignatureCommand extends Command
  8 +{
  9 +
  10 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Constants;
  5 +
  6 +
  7 +class CountryCode
  8 +{
  9 + public const TABLE = [
  10 +
  11 + ];
  12 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Constants;
  5 +
  6 +
  7 +class Logistics
  8 +{
  9 + public const TABLE = [
  10 +
  11 + ];
  12 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Constants;
  5 +
  6 +
  7 +class Package
  8 +{
  9 + public const TABLE = [
  10 +
  11 + ];
  12 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Constants;
  5 +
  6 +
  7 +class ResponseCode
  8 +{
  9 + public const STATUS_SUCCESS = 1;
  10 +
  11 +
  12 + public const STATUS_FAIL = 0;
  13 +
  14 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Constants;
  5 +
  6 +class WarehouseCode
  7 +{
  8 + public const TABLE = [
  9 + [
  10 + 'declare_code' => '0048',
  11 + 'declare_name' => '杭州下沙保税仓',
  12 + 'warehouse_code' => 'WC_HZXS_01',
  13 + 'warehouse_name' => '杭州下沙仓',
  14 + 'warehouse_type' => '保税仓'
  15 + ],
  16 + [
  17 + 'declare_code' => 'GZ_HP_BC',
  18 + 'declare_name' => '澳洲1号仓',
  19 + 'warehouse_code' => 'YMAZXNC',
  20 + 'warehouse_name' => '',
  21 + 'warehouse_type' => ''
  22 + ],
  23 + [
  24 + 'declare_code' => '',
  25 + 'declare_name' => '',
  26 + 'warehouse_code' => '',
  27 + 'warehouse_name' => '',
  28 + 'warehouse_type' => ''
  29 + ],
  30 + [
  31 + 'declare_code' => '',
  32 + 'declare_name' => '',
  33 + 'warehouse_code' => '',
  34 + 'warehouse_name' => '',
  35 + 'warehouse_type' => ''
  36 + ],
  37 + [
  38 + 'declare_code' => '',
  39 + 'declare_name' => '',
  40 + 'warehouse_code' => '',
  41 + 'warehouse_name' => '',
  42 + 'warehouse_type' => ''
  43 + ],
  44 + [
  45 + 'declare_code' => '',
  46 + 'declare_name' => '',
  47 + 'warehouse_code' => '',
  48 + 'warehouse_name' => '',
  49 + 'warehouse_type' => ''
  50 + ]
  51 + ];
  52 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Contracts;
  5 +
  6 +interface ClientInterface
  7 +{
  8 + public static function make(RequestInterface $request): ClientInterface;
  9 +
  10 + public function send(): ResponseInterface;
  11 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Contracts;
  5 +
  6 +
  7 +interface RequestInterface
  8 +{
  9 + public function append(string $name, $value);
  10 +
  11 + public function toArray(): array;
  12 +
  13 + public function toString(): string;
  14 +
  15 + public function getMethod(): string;
  16 +
  17 + public function getPath(): string;
  18 +
  19 + public function getContentType(): string;
  20 +
  21 + public function getVersion(): string;
  22 +
  23 + public function __invoke(): self;
  24 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Contracts;
  5 +
  6 +interface ResponseInterface
  7 +{
  8 + /**
  9 + * @return int
  10 + */
  11 + public function getStatusCode(): int;
  12 +
  13 + /**
  14 + * @return bool
  15 + */
  16 + public function isSuccess(): bool;
  17 +
  18 + /**
  19 + * @return string
  20 + */
  21 + public function getContents(): string;
  22 +
  23 + /**
  24 + * @return array
  25 + */
  26 + public function toArray(): array;
  27 +
  28 + /**
  29 + * @return string
  30 + */
  31 + public function __toString();
  32 +
  33 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Contracts;
  5 +
  6 +
  7 +use lackoxygen\TopWarehouse\Request\GetStockInventoryRequest;
  8 +use lackoxygen\TopWarehouse\Request\OrdersB2cAddRequest;
  9 +
  10 +interface TopWarehouseInterface
  11 +{
  12 + public function ordersB2cAdd(OrdersB2cAddRequest $ordersB2cAddRequest): ResponseInterface;
  13 +
  14 + public function getStockInventory(GetStockInventoryRequest $getStockInventoryRequest): ResponseInterface;
  15 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Exception;
  5 +
  6 +
  7 +class Exception extends \Exception
  8 +{
  9 +
  10 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Facades;
  5 +
  6 +
  7 +use Illuminate\Support\Facades\Facade;
  8 +
  9 +class TopWarehouseFacade extends Facade
  10 +{
  11 + protected static function getFacadeAccessor()
  12 + {
  13 + return 'topWarehouse';
  14 + }
  15 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Request;
  5 +
  6 +
  7 +class GetStockInventoryRequest extends Request
  8 +{
  9 + public $warehouse_id;
  10 +
  11 + public $goods_id;
  12 +
  13 + public $deliveryItemId;
  14 +
  15 + public $type;
  16 +
  17 + protected function initialize():void
  18 + {
  19 + $this->contentType = 'application/json';
  20 + $this->method = 'POST';
  21 + $this->path = '/inventory.do?method=epass.wms.stock.inventory.get';
  22 + }
  23 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Request;
  5 +
  6 +
  7 +class OrdersB2cAddRequest extends Request
  8 +{
  9 + public $shop_id;
  10 + public $order_type;
  11 + public $order_id;
  12 + public $created;
  13 + public $modified;
  14 + public $logistics_code;
  15 + public $pay_no;
  16 + public $pay_mode;
  17 + public $pay_time;
  18 + public $way_bill_no;
  19 + public $change_flag;
  20 + public $payment;
  21 + public $way_frt_fee;
  22 + public $way_frt_fee_cy;
  23 + public $way_ind_fee;
  24 + public $way_tax_fee;
  25 + public $discount;
  26 + public $warehouse_id;
  27 + public $declare_plan;
  28 + public $buyer_reg_no;
  29 + public $buyer_indentity_type;
  30 + public $buyer_telephone;
  31 + public $buyer_identity_card;
  32 + public $buyer_name;
  33 + public $receiver_name;
  34 + public $receiver_identity_type;
  35 + public $receiver_identity_card;
  36 + public $receiver_mobile;
  37 + public $receiver_phone;
  38 + public $identity_image_front;
  39 + public $identity_image_back;
  40 + public $receiver_country;
  41 + public $receiver_state;
  42 + public $receiver_city;
  43 + public $receiver_district;
  44 + public $receiver_address;
  45 + public $receiver_zip;
  46 + public $country;
  47 + public $notes;
  48 + public $order_goods;
  49 + public $index = [];
  50 +
  51 +
  52 +
  53 + public function initialize()
  54 + {
  55 + $this->path = '/order.do?method=epass.orders.b2c.add';
  56 + $this->method = 'POST';
  57 + }
  58 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Request;
  5 +
  6 +use lackoxygen\TopWarehouse\Contracts\RequestInterface;
  7 +use ReflectionClass;
  8 +use ReflectionProperty;
  9 +use Illuminate\Support\Arr;
  10 +
  11 +abstract class Request implements RequestInterface
  12 +{
  13 + /**
  14 + * @var array
  15 + */
  16 + protected $propertyAlias = [];
  17 +
  18 + /**
  19 + * @var string
  20 + */
  21 + protected $path = '';
  22 +
  23 + /**
  24 + * @var string
  25 + */
  26 + protected $method = 'GET';
  27 +
  28 + /**
  29 + * @var string
  30 + */
  31 + protected $version = '1.0';
  32 +
  33 + /**
  34 + * @var string
  35 + */
  36 + protected $contentType = 'application/x-www-form-urlencoded';
  37 +
  38 + final public function __construct() { }
  39 +
  40 + protected function initialize() { }
  41 +
  42 + /**
  43 + * @param string $name
  44 + * @param $value
  45 + *
  46 + * @return false
  47 + */
  48 + public function append(string $name, $value): bool
  49 + {
  50 + if (!property_exists($this, $name)) {
  51 + return false;
  52 + }
  53 + if (!is_array($this->{$name})) {
  54 + return false;
  55 + }
  56 + $array = &$this->{$name};
  57 + Arr::set($array, $name, $value);
  58 +
  59 + return true;
  60 + }
  61 +
  62 +
  63 + /**
  64 + * @return string
  65 + */
  66 + public function getMethod(): string
  67 + {
  68 + return $this->method;
  69 + }
  70 +
  71 + /**
  72 + * @return string
  73 + */
  74 + public function getPath(): string
  75 + {
  76 + return $this->path;
  77 + }
  78 +
  79 + /**
  80 + * @return string
  81 + */
  82 + public function getContentType(): string
  83 + {
  84 + return $this->contentType;
  85 + }
  86 +
  87 + /**
  88 + * @return string
  89 + */
  90 + public function getVersion(): string
  91 + {
  92 + return $this->version;
  93 + }
  94 +
  95 + /**
  96 + * @return array
  97 + */
  98 + public function toArray(): array
  99 + {
  100 + $reflection = new ReflectionClass($this);
  101 + $properties = $reflection->getProperties(ReflectionProperty::IS_PUBLIC);
  102 + $array = [];
  103 + foreach (Arr::pluck($properties, 'name') as $property) {
  104 + $array[$this->getPropertyAlias($property, $property)] = $this->{$property};
  105 + }
  106 +
  107 + return $array;
  108 + }
  109 +
  110 + /**
  111 + * @param $key
  112 + *
  113 + * @return bool
  114 + */
  115 + private function hasPropertyAlias($key): bool
  116 + {
  117 + return Arr::exists($this->propertyAlias, $key);
  118 + }
  119 +
  120 + /**
  121 + * @param $key
  122 + * @param string $default
  123 + *
  124 + * @return mixed|string
  125 + */
  126 + private function getPropertyAlias($key, $default = ''): string
  127 + {
  128 + if ($this->hasPropertyAlias($key)) {
  129 + return $this->propertyAlias[$key];
  130 + }
  131 +
  132 + return $default;
  133 + }
  134 +
  135 + /**
  136 + * @return string
  137 + */
  138 + public function toString(): string
  139 + {
  140 + return json_encode($this->toArray(), JSON_UNESCAPED_UNICODE);
  141 + }
  142 +
  143 + /**
  144 + * @return $this
  145 + */
  146 + public function __invoke(): RequestInterface
  147 + {
  148 + $this->initialize();
  149 +
  150 + return $this;
  151 + }
  152 +}
  1 +<?php
  2 +
  3 +namespace lackoxygen\TopWarehouse;
  4 +
  5 +use Illuminate\Support\Arr;
  6 +use lackoxygen\TopWarehouse\Contracts\ResponseInterface;
  7 +use lackoxygen\TopWarehouse\Utils\Json;
  8 +use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
  9 +
  10 +class Response implements ResponseInterface
  11 +{
  12 + /**
  13 + * @var PsrResponseInterface
  14 + */
  15 + protected $response;
  16 +
  17 + /**
  18 + * Response constructor.
  19 + *
  20 + * @param PsrResponseInterface $response
  21 + */
  22 + public function __construct(PsrResponseInterface $response)
  23 + {
  24 + $this->response = $response;
  25 + }
  26 +
  27 + public function getStatusCode(): int
  28 + {
  29 + return $this->response->getStatusCode();
  30 + }
  31 +
  32 + public function isSuccess(): bool
  33 + {
  34 + if (200 !== $this->getStatusCode()) {
  35 + return false;
  36 + }
  37 +
  38 + $body = $this->toArray();
  39 +
  40 + return Arr::get($body, 'status', 0) == 1;
  41 + }
  42 +
  43 + public function getContents(): string
  44 + {
  45 + return $this->response->getBody()->getContents();
  46 + }
  47 +
  48 + public function toArray(): array
  49 + {
  50 + return Json::decode($this->getContents());
  51 + }
  52 +
  53 + public function __toString()
  54 + {
  55 + return $this->getContents();
  56 + }
  57 +}
  1 +<?php
  2 +
  3 +namespace lackoxygen\TopWarehouse;
  4 +
  5 +use lackoxygen\TopWarehouse\Contracts\ResponseInterface;
  6 +use lackoxygen\TopWarehouse\Contracts\TopWarehouseInterface;
  7 +use lackoxygen\TopWarehouse\Request\GetStockInventoryRequest;
  8 +use lackoxygen\TopWarehouse\Request\OrdersB2cAddRequest;
  9 +
  10 +class TopWarehouse implements TopWarehouseInterface
  11 +{
  12 + public function ordersB2cAdd(OrdersB2cAddRequest $ordersB2cAddRequest): ResponseInterface
  13 + {
  14 + return Client::make($ordersB2cAddRequest)->send();
  15 + }
  16 +
  17 + public function getStockInventory(GetStockInventoryRequest $getStockInventoryRequest): ResponseInterface
  18 + {
  19 + return Client::make($getStockInventoryRequest)->send();
  20 + }
  21 +}
  1 +<?php
  2 +
  3 +namespace lackoxygen\TopWarehouse;
  4 +
  5 +use Illuminate\Support\ServiceProvider;
  6 +use Illuminate\Foundation\Application;
  7 +
  8 +class TopWarehouseServiceProvider extends ServiceProvider
  9 +{
  10 + /**
  11 + * @var string
  12 + */
  13 + public const CONFIG_NAME = 'top-warehouse';
  14 +
  15 +
  16 + /**
  17 + * @var bool
  18 + */
  19 + protected $defer = true;
  20 +
  21 + /**
  22 + * @var array
  23 + */
  24 + protected $commands = [
  25 +
  26 + ];
  27 +
  28 + /**
  29 + * Register any application services.
  30 + *
  31 + * @return void
  32 + */
  33 + public function register()
  34 + {
  35 + $this->commands($this->commands);
  36 + }
  37 +
  38 + public function boot()
  39 + {
  40 + if ($this->app instanceof Application && $this->app->runningInConsole()) {
  41 + $this->publishes([__DIR__ . '/../config/top-warehouse.php' => config_path('top-warehouse.php')]);
  42 + }
  43 + }
  44 +
  45 + public function provides()
  46 + {
  47 + return [];
  48 + }
  49 +
  50 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Utils;
  5 +
  6 +
  7 +class Json
  8 +{
  9 + public static function encode($array, int $flags = JSON_UNESCAPED_UNICODE, int $depth = 512)
  10 + {
  11 + return json_encode($array, $flags, $depth);
  12 + }
  13 +
  14 + public static function decode(string $json, ?bool $associative = true, int $depth = 512): array
  15 + {
  16 + return json_decode($json, $associative, $depth);
  17 + }
  18 +}
  1 +<?php
  2 +
  3 +
  4 +namespace lackoxygen\TopWarehouse\Utils;
  5 +
  6 +
  7 +class SignatureUtil
  8 +{
  9 + /**
  10 + * @param array $data
  11 + * @param string $secret
  12 + *
  13 + * @return string
  14 + */
  15 + public static function generate(array $data, string $secret): string
  16 + {
  17 + ksort($data);
  18 + $string = "";
  19 + foreach ($data as $key => $item) {
  20 + switch (gettype($item)) {
  21 + case null:
  22 + case '':
  23 + break;
  24 + case 'string':
  25 + if (strlen($item) > 0) {
  26 + $string .= "{$key}{$item}";
  27 + }
  28 + break;
  29 + case 'array':
  30 + $value = Json::encode($item);
  31 + $string .= "{$key}$value}";
  32 + break;
  33 + }
  34 + }
  35 +
  36 + return strtoupper(md5($secret . $string . $secret));
  37 + }
  38 +}