mirror of
https://gitee.com/hzchunfen/erp.git
synced 2025-11-30 22:20:45 +00:00
212 lines
8.3 KiB
PHP
212 lines
8.3 KiB
PHP
<?php
|
||
|
||
namespace App\Services\Ship\JingDong;
|
||
|
||
use App\Enum\Pickup\ConsignType;
|
||
use App\Models\BusinessOrder;
|
||
use App\Models\OrderItem;
|
||
use App\Models\Pickup;
|
||
use App\Models\Waybill;
|
||
use App\Services\Pickup\Exceptions\KdNiaoException;
|
||
use App\Utils\Env\EnvUtils;
|
||
use Carbon\Carbon;
|
||
use GuzzleHttp\Client;
|
||
use GuzzleHttp\Exception\GuzzleException;
|
||
use Illuminate\Support\Facades\Log;
|
||
use Lop\LopOpensdkPhp\Filters\ErrorResponseFilter;
|
||
use Lop\LopOpensdkPhp\Filters\IsvFilter;
|
||
use Lop\LopOpensdkPhp\Options;
|
||
use Lop\LopOpensdkPhp\Support\DefaultClient;
|
||
use Lop\LopOpensdkPhp\Support\GenericRequest;
|
||
use Psr\Http\Message\ResponseInterface;
|
||
|
||
class JingDongService
|
||
{
|
||
public $baseUrl;
|
||
public $appKey;
|
||
public $appSecret;
|
||
public $accessToken;
|
||
public $customerCode;
|
||
public static $CANCEL_TYPE = [
|
||
1 => '预约信息有误',
|
||
2 => '快递员无法取件',
|
||
3 => '上门太慢',
|
||
4 => '运费太贵',
|
||
7 => '联系不上快递员',
|
||
8 => '快递员要求取消',
|
||
11 => '其他(如疫情管控,无法寄 件)',
|
||
9 => '预约信息有误',
|
||
];
|
||
|
||
public function __construct()
|
||
{
|
||
$this->baseUrl = "https://api.jdl.com";
|
||
$this->appKey = "5ee218f6619e438db8755ee560c3eaa7";
|
||
$this->appSecret = "7ffb176f75014ebbb37061f051024bf3";
|
||
$this->accessToken = "4e411a1d178147cdb58b5579a0df378d";//每年都会过期 https://oauth.jdl.com/oauth/authorize?client_id=YOUR_APP_KEY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code
|
||
//生产环境域名:https://oauth.jdl.com 预发环境域名:https://uat-oauth.jdl.com
|
||
$this->domain = "FreshMedicineDelivery";//对接方案的编码 生鲜快递
|
||
$this->customerCode = "028K4188368";//月结编码
|
||
/*if (!EnvUtils::checkIsProduce()) {
|
||
//沙箱环境
|
||
$this->baseUrl = "https://test-api.jdl.com";
|
||
$this->appKey = "62d07644754843cc882fca7c01476c4f";
|
||
$this->appSecret = "0c2c8b6b7c10481ea639f6daa09ac02e";
|
||
$this->accessToken = "78c246c0ab564e67add6296a9eaf04a1";;//每年都会过期 https://oauth.jdl.com/oauth/authorize?client_id=YOUR_APP_KEY&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code
|
||
$this->customerCode = "27K1234912";//月结编码
|
||
}*/
|
||
|
||
}
|
||
|
||
public function request($body, $path)
|
||
{
|
||
// 生产环境: https://api.jdl.com
|
||
$client = new DefaultClient($this->baseUrl);
|
||
// 系统参数,应用的app_ley和app_secret,可从【控制台-应用管理-概览】中查看;access_token是用户授权时获取的令牌,用户授权相关说明请查看https://cloud.jdl.com/#/devSupport/53392
|
||
$isvFilter = new IsvFilter($this->appKey, $this->appSecret, $this->accessToken);
|
||
$errorResponseFilter = new ErrorResponseFilter();
|
||
|
||
$request = new GenericRequest();
|
||
$request->setDomain($this->domain);//对接方案的编码,应用订购对接方案后可在订阅记录查看
|
||
$request->setPath($path);//api的path,可在API文档查看
|
||
$request->setMethod("POST");//只支持POST
|
||
// 序列化后的JSON字符串
|
||
$request->setBody(json_encode([$body]));
|
||
|
||
// 为请求添加ISV模式过滤器,自动根据算法计算开放平台鉴权及签名信息
|
||
$request->addFilter($isvFilter);
|
||
// 为请求添加错误响应解析过滤器,如果不添加需要手动解析错误响应
|
||
$request->addFilter($errorResponseFilter);
|
||
|
||
$options = new Options();
|
||
|
||
$options->setAlgorithm(Options::MD5_SALT);
|
||
Log::info("京东请求body:{$path}", [$body]);
|
||
$response = $client->execute($request, $options);
|
||
$response = json_decode($response->getBody(), true);
|
||
Log::info("京东返回请求response", [$response]);
|
||
if (!isset($response['code']) || ($response['code'] != 0 && $response['code'] != 1000)) {
|
||
throw new \Exception($response['msg'] ?? "code异常");
|
||
}
|
||
return $response;
|
||
}
|
||
|
||
|
||
private function buildCargoes($extend)
|
||
{
|
||
return [
|
||
[
|
||
"quantity" => $extend["quantity"] ?? 1,
|
||
"goodsName" => "鲜花",
|
||
"volume" => ($extend['volume'] ?? 0) > 0 ? $extend['volume'] : 100,
|
||
"weight" => $extend['weight'] ?? 1,
|
||
"packageQty" => 1
|
||
]
|
||
];
|
||
}
|
||
|
||
public function buildContact($params)
|
||
{
|
||
return [
|
||
'senderName' => $params['name'] ?? '',
|
||
'senderPhone' => $params['mobile'] ?? '',
|
||
'senderAddress' => substr($params['province_name'] . $params['city_name'] . $params['area_name'] . $params['address_detail'], 0, 350),
|
||
];
|
||
}
|
||
|
||
public function createOrder(Waybill $pickup)
|
||
{
|
||
$path = "/freshmedicinedelivery/delivery/create/order/v1";
|
||
$pickupData = $pickup->toArray();
|
||
$body = [
|
||
"orderId" => $pickupData['object_id'],
|
||
"senderContactRequest" => [
|
||
'senderName' => $pickupData['sender_name'] ?? '',
|
||
'senderPhone' => $pickupData['sender_mobile'] ?? '',
|
||
'senderAddress' => substr($pickupData['sender_province'] . $pickupData['sender_city']
|
||
. $pickupData['sender_district'] . $pickupData['sender_detail'], 0, 350)
|
||
],
|
||
"customerCode" => $this->customerCode,
|
||
"remark" => $pickup['note'] ?? '',
|
||
"salePlatform" => '0010001',//京东
|
||
"cargoesRequest" => $this->buildCargoes($pickup),
|
||
"receiverContactRequest" => [
|
||
'receiverName' => $pickupData['recipient_name'] ?? '',
|
||
'receiverPhone' => $pickupData['recipient_mobile'] ?? '',
|
||
'receiverAddress' => substr($pickupData['recipient_province'] . $pickupData['recipient_city'] . $pickupData['recipient_district'] . $pickupData['recipient_detail'], 0, 350)
|
||
],
|
||
"channelOrderId" => $pickupData['order_sn'],
|
||
"promiseTimeType" => 26,//22:医药冷链 26:冷链专送,29医药专送
|
||
"goodsType" => 7,//1:普通,2:生鲜常温,5:鲜活,6:控温,7:冷藏,8:冷冻,9:深冷;21:医药冷藏,23:医药控温,24:医药常温,25:医药冷冻,27:医药深冷
|
||
//"pickUpStartTime" => Carbon::today()->startOfDay()->addHours(19)->toDateTimeString(),
|
||
//"pickUpEndTime" => Carbon::today()->startOfDay()->addHours(21)->toDateTimeString(),
|
||
];
|
||
dd($body);
|
||
$response = $this->request($body, $path);
|
||
return $response['data'];
|
||
|
||
}
|
||
|
||
|
||
public function cancelOrder(Waybill $pickup)
|
||
{
|
||
$path = "/freshmedicinedelivery/delivery/cancel/waybill/v1";
|
||
$pickupData = $pickup->toArray();
|
||
$body = [
|
||
"waybillNo" => $pickupData['waybill_code'],
|
||
"customerCode" => $this->customerCode,
|
||
"interceptReason" => "订单信息有误",
|
||
];
|
||
$response = $this->request($body, $path);
|
||
|
||
return $response['data'];
|
||
}
|
||
|
||
public function queryOrder(Waybill $pickup)
|
||
{
|
||
$path = "/ecap/v1/orders/details/query";
|
||
$pickupData = $pickup->toArray();
|
||
$body = [
|
||
"waybillCode" => $pickupData['ship_sn'] ?? '',
|
||
"orderCode" => $pickupData['out_order_sn'] ?? "",
|
||
"customerCode" => $this->customerCode,
|
||
"orderOrigin" => 2,
|
||
];
|
||
$response = $this->request($body, $path);
|
||
|
||
return $response['data'];
|
||
}
|
||
|
||
public function subscribe(Waybill $pickup)
|
||
{
|
||
$path = "/jd/tracking/subscribe";
|
||
$pickupData = $pickup->toArray();
|
||
$body = [
|
||
"referenceNumber" => $pickupData['ship_sn'] ?? '',
|
||
"referenceType" => 20000,
|
||
"customerCode" => $this->customerCode,
|
||
];
|
||
$this->domain = "Tracking_JD";//对接方案的编码
|
||
$response = $this->request($body, $path);
|
||
|
||
return $response['data'];
|
||
}
|
||
|
||
public function queryFee(Waybill $pickup)
|
||
{
|
||
$path = "/ecap/v1/orders/actualfee/query";
|
||
$pickupData = $pickup->toArray();
|
||
$body = [
|
||
"waybillCode" => $pickupData['ship_sn'] ?? '',
|
||
"orderCode" => $pickupData['out_order_sn'] ?? "",
|
||
"customerCode" => $this->customerCode,
|
||
"orderOrigin" => 2,
|
||
];
|
||
$response = $this->request($body, $path);
|
||
|
||
return $response['data'];
|
||
}
|
||
|
||
}
|
||
|