| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- <?php
- namespace common\components\delivery\services\adapter;
- use common\components\delivery\helpers\HttpClient;
- use common\components\delivery\helpers\SignHelper;
- use common\components\delivery\platform\dada\Dada;
- use Yii;
- /**
- * 达达(DaDa)配送平台适配器
- *
- * 基于达达开放平台 API 接口规范进行封装
- * API 文档参考:达达开放平台 - 接口调用协议与签名算法
- */
- class DadaAdapter extends Dada implements Adapter
- {
- /**
- * 获取已开通城市列表
- *
- * 通过此接口可获取到达达配送业务所有已开通的城市列表信息
- *
- * @return array 包含城市列表的响应数据
- * 示例结构:
- * [
- * 'status' => 'success',
- * 'code' => 0,
- * 'msg' => '成功',
- * 'result' => [
- * 'cityList' => [
- * [
- * 'cityCode' => '110101',
- * 'cityName' => '东城区',
- * 'provinceName' => '北京市',
- * ],
- * // ... 更多城市
- * ]
- * ]
- * ]
- */
- public function cityList()
- {
- // 业务参数为空时使用空字符串
- $body = '';
-
- // 构建完整的 API 请求参数
- $payload = $this->buildRequestPayload('cityList', $body);
-
- // 发送 POST 请求
- $resp = HttpClient::post("{$this->baseUrl}/cityList", $payload);
-
- return $resp;
- }
- /**
- * 创建订单(指派订单给配送员)
- *
- * 根据达达官方文档实现下单功能
- *
- * @param array $data 订单数据,结构参考:
- * [
- * 'order_id' => '订单编号' (必需), // 商户系统内部订单编号
- * 'shop_no' => '门店编号' (必需), // 门店编号
- * 'transporter_id' => 配送员ID (必需), // 指定配送员ID(可选,为空则由系统自动分配)
- * 'receiver_name' => '收货人名称' (可选),
- * 'receiver_address' => '收货地址' (可选),
- * 'receiver_phone' => '收货人电话' (可选),
- * 'receiver_lng' => 经度 (可选),
- * 'receiver_lat' => 纬度 (可选),
- * 'cargo_price' => 货物价格(分) (可选),
- * 'tips' => 小费(分) (可选),
- * 'distance' => 距离(米) (可选),
- * 'prepare_time' => 商品准备时间 (可选), // 单位:秒
- * 'remark' => '备注' (可选),
- * 'callback' => '回调地址' (可选),
- * ]
- * @return array API 响应结果
- */
- public function createOrder($data)
- {
- // 验证必需字段
- if (empty($data['order_id']) || empty($data['shop_no'])) {
- return [
- 'code' => -1,
- 'msg' => '缺少必需参数: order_id 和 shop_no'
- ];
- }
- // 构建业务参数(按达达 API 规范)
- $apiData = [
- 'order_id' => $data['order_id'],
- 'shop_no' => $data['shop_no'],
- ];
- // 如果指定了配送员ID,添加到请求
- if (isset($data['transporter_id'])) {
- $apiData['transporter_id'] = (int)$data['transporter_id'];
- }
- // 可选参数
- if (!empty($data['receiver_name'])) {
- $apiData['receiver_name'] = $data['receiver_name'];
- }
- if (!empty($data['receiver_address'])) {
- $apiData['receiver_address'] = $data['receiver_address'];
- }
- if (!empty($data['receiver_phone'])) {
- $apiData['receiver_phone'] = $data['receiver_phone'];
- }
- if (isset($data['receiver_lng']) && $data['receiver_lng'] !== '') {
- $apiData['receiver_lng'] = (double)$data['receiver_lng'];
- }
- if (isset($data['receiver_lat']) && $data['receiver_lat'] !== '') {
- $apiData['receiver_lat'] = (double)$data['receiver_lat'];
- }
- if (isset($data['cargo_price'])) {
- $apiData['cargo_price'] = (int)$data['cargo_price'];
- }
- if (isset($data['tips'])) {
- $apiData['tips'] = (int)$data['tips'];
- }
- if (isset($data['distance'])) {
- $apiData['distance'] = (int)$data['distance'];
- }
- if (isset($data['prepare_time'])) {
- $apiData['prepare_time'] = (int)$data['prepare_time'];
- }
- if (!empty($data['remark'])) {
- $apiData['remark'] = $data['remark'];
- }
- if (!empty($data['callback'])) {
- $apiData['callback'] = $data['callback'];
- }
- // 将业务参数转换为 JSON 字符串
- $body = json_encode($apiData, JSON_UNESCAPED_UNICODE);
- // 构建完整的 API 请求参数
- $payload = $this->buildRequestPayload('orderAddRequest', $body);
- // 发送 POST 请求
- $resp = HttpClient::post("{$this->baseUrl}/orderAddRequest", $payload);
- return $resp;
- }
- /**
- * 获取订单运费报价
- *
- * 根据达达官方文档实现订单运费估价功能
- *
- * @param array $data 运费估价参数,结构参考:
- * [
- * 'shop_no' => '门店编号' (必需),
- * 'origin_id' => '原始订单ID' (必需), // 商户侧订单编号
- * 'receiver_address' => '收货地址' (必需),
- * 'receiver_phone' => '收货人电话' (必需),
- * 'receiver_lng' => 经度 (必需),
- * 'receiver_lat' => 纬度 (必需),
- * 'cargo_price' => 货物价格(分) (可选), // 商品价格,单位为分
- * 'distance' => 距离(米) (可选),
- * 'prepare_time' => 商品准备时间 (可选), // 单位:秒
- * ]
- * @return array|null 运费报价结果
- */
- public function getPrice($data)
- {
- // 验证必需字段
- if (empty($data['shop_no']) || empty($data['origin_id']) ||
- empty($data['receiver_address']) || empty($data['receiver_phone']) ||
- !isset($data['receiver_lng']) || !isset($data['receiver_lat'])) {
- return [
- 'code' => -1,
- 'msg' => '缺少必需参数'
- ];
- }
- // 构建业务参数(按达达 API 规范)
- $apiData = [
- 'shop_no' => $data['shop_no'],
- 'origin_id' => $data['origin_id'],
- 'receiver_address' => $data['receiver_address'],
- 'receiver_phone' => $data['receiver_phone'],
- 'receiver_lng' => (double)$data['receiver_lng'],
- 'receiver_lat' => (double)$data['receiver_lat'],
- ];
- // 可选参数
- if (isset($data['cargo_price'])) {
- $apiData['cargo_price'] = (int)$data['cargo_price'];
- }
- if (isset($data['distance'])) {
- $apiData['distance'] = (int)$data['distance'];
- }
- if (isset($data['prepare_time'])) {
- $apiData['prepare_time'] = (int)$data['prepare_time'];
- }
- // 将业务参数转换为 JSON 字符串
- $body = json_encode($apiData, JSON_UNESCAPED_UNICODE);
- // 构建完整的 API 请求参数
- $payload = $this->buildRequestPayload('queryDeliverFee', $body);
- // 发送 POST 请求
- $resp = HttpClient::post("{$this->baseUrl}/queryDeliverFee", $payload);
- // 处理响应
- if (isset($resp['status']) && $resp['status'] === 'success' && $resp['code'] == 0) {
- $result = $resp['result'] ?? [];
- return [
- 'code' => 0,
- 'platform' => 'dada',
- 'deliver_fee' => $result['deliver_fee'] ?? 0, // 配送费(分)
- 'distance' => $result['distance'] ?? 0, // 距离(米)
- 'duration' => $result['duration'] ?? 0, // 配送时间(分钟)
- 'tips' => $result['tips'] ?? 0, // 小费(分)
- ];
- }
- return [
- 'code' => $resp['code'] ?? -1,
- 'msg' => $resp['msg'] ?? 'Unknown error',
- 'data' => null
- ];
- }
- /**
- * 生成随机数字符串(备用方法,如需要使用)
- *
- * @param int $length 长度
- * @return string 随机字符串
- */
- protected function generateNonceStr($length = 16)
- {
- $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
- $str = '';
- for ($i = 0; $i < $length; $i++) {
- $str .= $chars[random_int(0, strlen($chars) - 1)];
- }
- return $str;
- }
- public function addTip($data)
- {
- // TODO: Implement addTip() method.
- }
- public function buildPriceRequest($data, $orderTime)
- {
- // TODO: Implement buildPriceRequest() method.
- }
- }
|