320 lines
11 KiB
PHP
320 lines
11 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2016~2022 https://www.crmeb.com All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||
// +----------------------------------------------------------------------
|
||
// | Author: CRMEB Team <admin@crmeb.com>
|
||
// +----------------------------------------------------------------------\
|
||
namespace crmeb\services\delivery\storage;
|
||
|
||
use crmeb\basic\BaseStorage;
|
||
use crmeb\interfaces\DeliveryInterface;
|
||
use think\exception\ValidateException;
|
||
|
||
class Dada extends BaseStorage implements DeliveryInterface
|
||
{
|
||
const BASE_URL = 'https://newopen.imdada.cn';
|
||
|
||
const ADD_MERCHANT = '/merchantApi/merchant/add';
|
||
|
||
const ADD_SHOP = '/api/shop/add';
|
||
|
||
const UPDATE_SHOP = '/api/shop/update';
|
||
|
||
const GET_CITY_CODE = '/api/cityCode/list';
|
||
|
||
const GET_SHOP_DETAIL = '/api/shop/detail';
|
||
|
||
const GET_ORDER_PRICE = '/api/order/queryDeliverFee';
|
||
|
||
const ADD_ORDER_AFTER_QUERY = '/api/order/addAfterQuery';
|
||
|
||
const ADD_ORDER_STSATUS_QUERY = '/api/order/status/query';
|
||
|
||
const GET_REASONS = '/api/order/cancel/reasons';
|
||
|
||
const CANCEL_ORDER = '/api/order/formalCancel';
|
||
|
||
const GET_BALANCE = '/api/balance/query';
|
||
|
||
const GET_RECHARGE = '/api/recharge';
|
||
|
||
public $config;
|
||
|
||
public function initialize(array $config)
|
||
{
|
||
$this->config = $config;
|
||
}
|
||
|
||
//创建商户
|
||
public function addMerchant($data)
|
||
{
|
||
return $this->sendRequest(self::ADD_MERCHANT, $data);
|
||
}
|
||
|
||
//创建门店
|
||
public function addShop($data)
|
||
{
|
||
$parmas = [];
|
||
foreach ($data as $key => $item) {
|
||
if (!($item['lng']) || !($item['lat']))
|
||
throw new ValidateException('经纬度不能为空');
|
||
if (!($item['phone']) || !($item['contact_name']))
|
||
throw new ValidateException('联系人信息不能为空');
|
||
if (!($item['business']))
|
||
throw new ValidateException('配送物品分类不能为空');
|
||
if (!($item['station_name']) || !$item['station_address'])
|
||
throw new ValidateException('门店信息不能为空');
|
||
$value = [
|
||
'lng' => (float)$item['lng'],
|
||
'lat' => (float)$item['lat'],
|
||
'phone' => $item['phone'],
|
||
'business' => (int)$item['business'],
|
||
'contact_name' => $item['contact_name'],
|
||
'station_name' => $item['station_name'],
|
||
'station_address' => $item['station_address'],
|
||
'status' => 1,
|
||
'origin_shop_id' => $item['origin_shop_id'],
|
||
];
|
||
if (isset($item['username']) && $item['username']) $value['username'] = $item['username'];
|
||
if (isset($item['password']) && $item['password']) $value['password'] = $item['password'];
|
||
$parmas[] = $value;
|
||
}
|
||
return $this->sendRequest(self::ADD_SHOP, $parmas);
|
||
}
|
||
|
||
//更新门店
|
||
public function updateShop($data)
|
||
{
|
||
$params['origin_shop_id'] = $data['origin_shop_id'];
|
||
if (isset($data['new_shop_id'])) $params['new_shop_id'] = $data['new_shop_id'];
|
||
if (isset($data['station_name'])) $params['station_name'] = $data['station_name'];
|
||
if (isset($data['business'])) $params['business'] = $data['business'];
|
||
if (isset($data['station_address'])) $params['station_address'] = $data['station_address'];
|
||
if (isset($data['lng'])) $params['lng'] = $data['lng'];
|
||
if (isset($data['lat'])) $params['lat'] = $data['lat'];
|
||
if (isset($data['contact_name'])) $params['contact_name'] = $data['contact_name'];
|
||
if (isset($data['phone'])) $params['phone'] = $data['phone'];
|
||
if (isset($data['status'])) $params['status'] = $data['status'];
|
||
return $this->sendRequest(self::UPDATE_SHOP, $params);
|
||
}
|
||
|
||
//预发布订单
|
||
public function addOrder($data)
|
||
{
|
||
$params = [
|
||
'deliveryNo' => $data['deliveryNo'],
|
||
];
|
||
return $this->sendRequest(self::ADD_ORDER_AFTER_QUERY, $params);
|
||
}
|
||
|
||
//计算订单价格
|
||
public function getOrderPrice($data)
|
||
{
|
||
$params = [
|
||
'shop_no' => $data['shop_no'],
|
||
'origin_id' => $data['origin_id'],
|
||
'city_code' => $data['city_code'],
|
||
'cargo_price' => $data['cargo_price'],
|
||
'is_prepay' => $data['is_prepay'],
|
||
'receiver_name' => $data['receiver_name'],
|
||
'receiver_address'=> $data['receiver_address'],
|
||
'callback' => $data['callback_url'],
|
||
'cargo_weight' => $data['cargo_weight'],
|
||
'receiver_phone' => $data['receiver_phone'],
|
||
'is_finish_code_needed'=> $data['is_finish_code_needed'],
|
||
];
|
||
return $this->sendRequest(self::GET_ORDER_PRICE, $params);
|
||
}
|
||
|
||
//获取订单详情
|
||
public function getOrderDetail($data)
|
||
{
|
||
$params['order_id'] = $data['origin_id'];
|
||
return $this->sendRequest(self::ADD_ORDER_STSATUS_QUERY, $params);
|
||
}
|
||
//取消订单
|
||
public function cancelOrder($data)
|
||
{
|
||
$params['order_id'] = $data['origin_id'];
|
||
$params['cancel_reason'] = $data['cancel_reason'] ?? '无';
|
||
$params['cancel_reason_id'] = $data['reason'];
|
||
return $this->sendRequest(self::CANCEL_ORDER, $params);
|
||
}
|
||
//获取充值地址
|
||
public function getRecharge($data =[])
|
||
{
|
||
$params = [
|
||
'amount' => $data['amount'] ?? 100,
|
||
'category'=> $data['category'] ?? 'PC',
|
||
];
|
||
return $this->sendRequest(self::GET_RECHARGE, $params);
|
||
}
|
||
//获取余额
|
||
public function getBalance($data)
|
||
{
|
||
$params['category'] = $data['category'] ?? 3;
|
||
$res = $this->sendRequest(self::GET_BALANCE, $params);
|
||
return [
|
||
'deliverBalance' => $res['deliverBalance']
|
||
];
|
||
}
|
||
//支付小费
|
||
public function addTip($data)
|
||
{
|
||
}
|
||
//取消原因
|
||
public function reasons($data = '')
|
||
{
|
||
$options = $this->sendRequest(self::GET_REASONS, $data);
|
||
foreach ($options as $option) {
|
||
$value = $option['id'];
|
||
$label = $option['reason'];
|
||
$res[] = compact('value','label');
|
||
}
|
||
return $res;
|
||
}
|
||
//获取城市信息
|
||
public function getCity($data = '')
|
||
{
|
||
$res = $this->sendRequest(self::GET_CITY_CODE, $data);
|
||
foreach ($res as $item) {
|
||
$data[] = [
|
||
'key' => $item['cityName'],
|
||
'label' => $item['cityName'],
|
||
];
|
||
}
|
||
return $data;
|
||
}
|
||
|
||
public function getShopDetail($id)
|
||
{
|
||
$data = ['origin_shop_id' => $id];
|
||
return $this->sendRequest(self::GET_SHOP_DETAIL, $data);
|
||
}
|
||
|
||
public function getBusiness()
|
||
{
|
||
return [
|
||
['key' => 1 , 'label' => '食品小吃'],
|
||
['key' => 2 , 'label' => '饮料'],
|
||
['key' => 3 , 'label' => '鲜花绿植'],
|
||
['key' => 5 , 'label' => '其他'],
|
||
['key' => 8 , 'label' => '文印票务'],
|
||
['key' => 9 , 'label' => '便利店'],
|
||
['key' => 13 , 'label' => '水果生鲜'],
|
||
['key' => 19 , 'label' => '同城电商'],
|
||
['key' => 20 , 'label' => '医药'],
|
||
['key' => 21 , 'label' => '蛋糕'],
|
||
['key' => 24 , 'label' => '酒品'],
|
||
['key' => 25 , 'label' => '小商品市场'],
|
||
['key' => 26 , 'label' => '服装'],
|
||
['key' => 27 , 'label' => '汽修零配'],
|
||
['key' => 28 , 'label' => '数码家电'],
|
||
['key' => 29 , 'label' => '小龙虾/烧烤'],
|
||
['key' => 31 , 'label' => '超市'],
|
||
['key' => 51 , 'label' => '火锅'],
|
||
['key' => 53 , 'label' => '个护美妆'],
|
||
['key' => 55 , 'label' => '母婴'],
|
||
['key' => 57 , 'label' => '家居家纺'],
|
||
['key' => 59 , 'label' => '手机'],
|
||
['key' => 61 , 'label' => '家装'],
|
||
['key' => 63 , 'label' => '成人用品'],
|
||
];
|
||
}
|
||
|
||
public function sendRequest($api, $params)
|
||
{
|
||
$url = self::BASE_URL . $api;
|
||
$params = $this->bulidRequestParams($params);
|
||
$response = $this->httpRequestWithPost($url, $params);
|
||
$data = $this->getMessage($response);
|
||
return $data;
|
||
}
|
||
|
||
/**
|
||
* 构造请求数据
|
||
* data:业务参数,json字符串
|
||
*/
|
||
public function bulidRequestParams($params)
|
||
{
|
||
$requestParams = array();
|
||
$requestParams['app_key'] = $this->config['app_key'];
|
||
$requestParams['body'] = json_encode($params);
|
||
$requestParams['format'] = 'json';
|
||
$requestParams['v'] = '1.0';
|
||
$requestParams['source_id'] = $this->config['source_id'];
|
||
$requestParams['timestamp'] = time();
|
||
$requestParams['signature'] = $this->_sign($requestParams);
|
||
return json_encode($requestParams);
|
||
}
|
||
|
||
/**
|
||
* 签名生成signature
|
||
*/
|
||
public function _sign($data)
|
||
{
|
||
//1.升序排序
|
||
ksort($data);
|
||
//2.字符串拼接
|
||
$args = "";
|
||
foreach ($data as $key => $value) {
|
||
$args .= $key . $value;
|
||
}
|
||
$args = $this->config['app_secret'] . $args . $this->config['app_secret'];
|
||
//3.MD5签名,转为大写
|
||
$sign = strtoupper(md5($args));
|
||
return $sign;
|
||
}
|
||
|
||
/**
|
||
* 发送请求,POST
|
||
* @param $url 指定URL完整路径地址
|
||
* @param $data 请求的数据
|
||
*/
|
||
public function httpRequestWithPost($url, $data, $headers = [])
|
||
{
|
||
$headers = array(
|
||
'Content-Type: application/json',
|
||
);
|
||
$curl = curl_init($url);
|
||
curl_setopt($curl, CURLOPT_URL, $url);
|
||
curl_setopt($curl, CURLOPT_HEADER, false);
|
||
curl_setopt($curl, CURLOPT_POST, true);
|
||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
|
||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||
curl_setopt($curl, CURLOPT_TIMEOUT, 3);
|
||
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||
$resp = curl_exec($curl);
|
||
$info = curl_getinfo($curl);
|
||
curl_close($curl);
|
||
if (isset($info['http_code']) && $info['http_code'] == 200) {
|
||
return $resp;
|
||
}
|
||
return ;
|
||
}
|
||
|
||
protected function getMessage($json, $message = '未知错误!')
|
||
{
|
||
$data = json_decode($json, true);
|
||
if ($data['code'] !== 0) {
|
||
isset($data['msg']) && $message = $data['msg'];
|
||
if ($data['errorCode'] == 7718) {
|
||
foreach ($data['result']['failedList'] as $datum) {
|
||
$message .= ':'.$datum['shopName'].'/'. $datum['msg'].';';
|
||
}
|
||
}
|
||
throw new ValidateException('【达达错误提示】:'.$message);
|
||
} else {
|
||
if ($data['status'] == 'success') return $data['result'] ?? $data;
|
||
return $data;
|
||
|
||
}
|
||
}
|
||
|
||
|
||
}
|