Api.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549
  1. <?php
  2. namespace addons\QiJuhe\common\api;
  3. use Yii;
  4. use yii\base\BaseObject;
  5. use yii\helpers\Json;
  6. class Api extends BaseObject
  7. {
  8. const API_RUL = "https://zhongtai.qijianshigw.com/supplyapi/";
  9. public $app_host;
  10. public $app_key;
  11. public $app_secret;
  12. public $mall_id;
  13. public $supply_id;
  14. public $token;
  15. public $error;
  16. public $api_list = [
  17. 'getToken' => '/app/application/getToken',
  18. 'getSupplySource' => '/app/application/getSupplySource',
  19. 'getCategory' => '/app/category/getCategory',
  20. 'getAllCategory' => '/app/category/tree',
  21. 'storageList' => '/app/product/storage/list',
  22. 'deleteStorage' => '/app/product/storage/deleteStorage',
  23. 'addStorage' => '/app/product/storage/addStorage',
  24. 'getGoodsInfo' => '/app/product/storage/detailList',
  25. 'goodsInfo' => '/app/product/storage/detailList',
  26. 'availableCheck' => '/app/order/availableCheck',
  27. 'createOreder' => '/app/order',
  28. 'getOrderInfo' => '/app/product/storage/detailList',
  29. 'orderLogistic' => '/app/order/Logistic',
  30. 'orderBeforeCheck' => '/app/order/beforeCheck',
  31. 'orderReceive' => '/app/order/receive',
  32. 'getAfterSales' => '/app/afterSales/get', // 通过售后id获取售后详情
  33. 'orderAfterSalesCreate' => '/app/afterSales/orderAfterSalesCreate', // 通过订单id/采购端订单号 发起整个订单的售后
  34. 'afterSalesReason' => '/app/afterSales/reason/list', // 获取售后原因
  35. 'findShopAddressByOrderId' => '/app/supplier/findShopAddressByOrderId', // 通过售后id获取默认商家售后退货地址
  36. 'afterSalesSend' => '/app/afterSales/send', //
  37. 'afterSalesList' => '/app/afterSales/list', // 获取售后列表
  38. 'afterSalesClose' => '/app/afterSales/close', // 关闭售后
  39. 'getSuppliers' => '/app/supplier/getSuppliers', // 获取供应商
  40. 'afterSalesCreate' => '/app/afterSales/create',
  41. 'orderDetail' => '/app/order/orderDetail', // 通过订单id/订单编号订单详情
  42. 'getAfterSalesTypeNameMap' => '/app/afterSales/getAfterSalesTypeNameMap', // 获取订单支持的售后方式
  43. 'refundUserReceive' => '/app/afterSales/userReceive', // 售后用户收货
  44. 'getAfterSalesByOrderItemId'=> '/app/afterSales/getAfterSalesByOrderItemId', // 通过子订单id获取售后详情
  45. 'orderDetailByThirdOrderSn' => '/app/order/orderDetailByThirdOrderSn', // 通过子订单id获取售后详情
  46. 'getGatherSupplyAndSource' => '/app/application/getGatherSupplyAndSource',
  47. ];
  48. /**
  49. * 初始
  50. *
  51. * @param array $config
  52. */
  53. public function __construct($config = [])
  54. {
  55. if (empty($config['app_key']) && empty($this->app_key)) {
  56. if (empty($config['mall_id'])) {
  57. throw new \Exception('请至少配置mall—id');
  58. }
  59. }
  60. parent::__construct($config);
  61. }
  62. public function getGatherSupplyAndSource()
  63. {
  64. $action = __FUNCTION__; //请求资源名
  65. return $this->request($action);
  66. }
  67. /**
  68. * 获取token
  69. * @param $param
  70. * @param $method
  71. *
  72. * @return array|bool
  73. */
  74. public function getToken($param = [], $method = 'post')
  75. {
  76. $action = __FUNCTION__; //请求资源名
  77. $param['app_key'] = $this->app_key;
  78. $param['app_secret'] = $this->app_secret;
  79. return $this->request($action, $param, $method);
  80. }
  81. /**
  82. * 可用中台
  83. *
  84. * @return boolean|array
  85. */
  86. public function getSupplySource()
  87. {
  88. $action = __FUNCTION__; //请求资源名
  89. return $this->request($action);
  90. }
  91. /**
  92. * 获取售后原因
  93. *
  94. * @param integer $after_sale_type
  95. * @param integer $is_received
  96. * @return boolean|array
  97. */
  98. public function afterSalesReason($after_sale_type, $is_received)
  99. {
  100. $action = __FUNCTION__; //请求资源名
  101. return $this->request($action, compact('after_sale_type', 'is_received'));
  102. }
  103. /**
  104. * 获取供应商列表
  105. *
  106. * @return boolean|array
  107. */
  108. public function getSuppliers()
  109. {
  110. $action = __FUNCTION__; //请求资源名
  111. return $this->request($action);
  112. }
  113. /**
  114. * 取消售后
  115. *
  116. * @param integer $id
  117. * @return boolean|array
  118. */
  119. public function afterSalesClose($id)
  120. {
  121. $action = __FUNCTION__; //请求资源名
  122. return $this->request($action, compact('id'), 'post');
  123. }
  124. /**
  125. * 获取售后列表
  126. *
  127. * @param string $third_order_sn
  128. * @return array
  129. */
  130. public function afterSalesList($third_order_sn)
  131. {
  132. $params['pageSize'] = 100;
  133. $params['page'] = 1;
  134. // $params['status'] = 1;
  135. $params['third_order_sn'] = $third_order_sn;
  136. $action = __FUNCTION__; //请求资源名
  137. return $this->request($action, $params);
  138. }
  139. /**
  140. * 获取全部分类
  141. *
  142. * @return boolean|array
  143. */
  144. public function getAllCategory()
  145. {
  146. $action = __FUNCTION__; //请求资源名
  147. return $this->request($action);
  148. }
  149. /**
  150. * 获取分类
  151. *
  152. * @param integer $parent_id
  153. * @return boolean|array
  154. */
  155. public function getCategory($parent_id = 0)
  156. {
  157. $action = __FUNCTION__; //请求资源名
  158. $param = $parent_id > 0 ? ['parent_id' => $parent_id] : [];
  159. return $this->request($action, $param);
  160. }
  161. /**
  162. * 通过订单id/采购端订单号 发起整个订单的售后
  163. *
  164. * @param array $params
  165. * [
  166. * order_id => 售后订单id 订单id与采购端订单号两个必传一个
  167. * third_order_sn => 采购端订单号 订单id与采购端订单号两个必传一个
  168. * reason_type => 售后原因 售后原因(售后原因API返回)
  169. * reason => 售后原因是 其他的的时候填写 否
  170. * description => 描述 否
  171. * is_received => 是否收到货 1是0否 是
  172. * detail_images => 图片凭证 否
  173. * refund_type => 退款还是退货退款 0退款 1退货退款
  174. * ]
  175. * @see https://www.yunzmall.com/plugins/shop_server/knowledge/knowledge_detail/919?base_id=14&i=10
  176. * @return boolean|array
  177. */
  178. public function orderAfterSalesCreate($params, $method = 'post')
  179. {
  180. $action = __FUNCTION__; //请求资源名
  181. return $this->request($action, $params, $method);
  182. }
  183. /**
  184. * 子订单申请售后
  185. *
  186. * @param array $params
  187. * @param string $method
  188. * @return boolean|array
  189. * @see https://www.yunzmall.com/plugins/shop_server/knowledge/knowledge_detail/910?base_id=14&i=10
  190. */
  191. public function afterSalesCreate(array $params, string $method = 'post')
  192. {
  193. $action = __FUNCTION__; //请求资源名
  194. return $this->request($action, $params, $method);
  195. }
  196. /**
  197. * 通过售后id获取售后详情
  198. *
  199. * @param integer $id 售后id
  200. * @return boolean|array
  201. */
  202. public function getAfterSales($id)
  203. {
  204. $action = __FUNCTION__; //请求资源名
  205. return $this->request($action, compact('id'));
  206. }
  207. /**
  208. * 通过订单id/采购端订单号获取默认售后收货地址
  209. *
  210. * @param array $params
  211. * @param string $method
  212. * @return array
  213. * @see https://www.yunzmall.com/plugins/shop_server/knowledge/knowledge_detail/916?base_id=14&i=10
  214. */
  215. public function findShopAddressByOrderId($after_sales_id)
  216. {
  217. $action = __FUNCTION__; //请求资源名
  218. return $this->request($action, compact('after_sales_id'));
  219. }
  220. /**
  221. * 售后发货
  222. *
  223. * @param array $params
  224. * @param string $method
  225. * @return array
  226. */
  227. public function afterSalesSend($params, $method = 'post')
  228. {
  229. $action = __FUNCTION__; //请求资源名
  230. return $this->request($action, $params, $method);
  231. }
  232. /**
  233. * 平台列表[淘宝、jd、]
  234. *
  235. * @param [type] $param
  236. * @return array
  237. */
  238. public function storageList($param)
  239. {
  240. $action = __FUNCTION__; //请求资源名
  241. $data = $this->request($action, $param, 'post');
  242. if (empty($data['list'])) {
  243. $data['list'] = [];
  244. $data['page_count'] = 0;
  245. $data['currentPage'] = 0;
  246. return $data;
  247. } else {
  248. $total = $data['total'];
  249. $data['page_count'] = ceil($total / $param['pageSize']);
  250. $data['currentPage'] = $param['page'] + 1;
  251. return $data;
  252. }
  253. }
  254. /**
  255. * 获取商品详情
  256. *
  257. * @param array $goods_id
  258. * @return array
  259. */
  260. public function goodsInfo(array $goods_id)
  261. {
  262. $action = __FUNCTION__; //请求资源名
  263. $ids = [];
  264. foreach ($goods_id as $id) {
  265. $ids[] = intval($id);
  266. }
  267. $data = $this->request($action, ['ids' => $ids], 'post');
  268. return $data['list'] ?? [];
  269. }
  270. /**
  271. * 获取商品详情属性
  272. *
  273. * @param integer $goods_id
  274. * @return array
  275. */
  276. public function getGoodsInfo($ids)
  277. {
  278. $ids = is_array($ids) ? $ids : [$ids];
  279. $action = __FUNCTION__; //请求资源名
  280. return $this->request($action, compact('ids'), 'post');
  281. }
  282. /**
  283. * 添加选品库
  284. *
  285. * @param array $ids
  286. * @return boolean|array
  287. */
  288. public function addStorage($ids)
  289. {
  290. $ids = is_array($ids) ? $ids : [$ids];
  291. $data = [];
  292. foreach ($ids as $id) {
  293. $data[] = intval($id);
  294. }
  295. $action = __FUNCTION__; //请求资源名
  296. return $this->request($action, ['ids' => $data], 'post');
  297. }
  298. /**
  299. * 删除选品库
  300. *
  301. * @param array $ids
  302. * @return boolean|array
  303. */
  304. public function deleteStorage($ids)
  305. {
  306. $ids = is_array($ids) ? $ids : [$ids];
  307. $data = [];
  308. foreach ($ids as $id) {
  309. $data[] = intval($id);
  310. }
  311. $action = __FUNCTION__; //请求资源名
  312. return $this->request($action, ['ids' => $data], 'post');
  313. }
  314. /**
  315. * 可售检测
  316. *
  317. * @param array $data
  318. * @return boolean|array
  319. */
  320. public function availableCheck($data)
  321. {
  322. $action = __FUNCTION__; // 请求资源名
  323. return $this->request($action, $data, 'post');
  324. }
  325. /**
  326. * 订单售前检测
  327. *
  328. * @param array $data
  329. * @return boolean|array
  330. */
  331. public function orderBeforeCheck($data)
  332. {
  333. $action = __FUNCTION__; // 请求资源名
  334. return $this->request($action, $data, 'post');
  335. }
  336. /**
  337. * 下单
  338. *
  339. * @param array $data
  340. * @return boolean|array
  341. */
  342. public function createOreder($data)
  343. {
  344. $action = __FUNCTION__; // 请求资源名
  345. return $this->request($action, $data, 'post');
  346. }
  347. /**
  348. * 订单物流查询
  349. *
  350. * @param string $order_sn
  351. * @return boolean|array
  352. */
  353. public function orderLogistic($order_sn)
  354. {
  355. $action = __FUNCTION__; // 请求资源名
  356. return $this->request($action, ['order_sn' => $order_sn], 'post');
  357. }
  358. public function orderReceive($id)
  359. {
  360. $action = __FUNCTION__; // 请求资源名
  361. return $this->request($action, ['order_id' => $id], 'post');
  362. }
  363. /**
  364. * 获取订单详情
  365. *
  366. * @param array $ids
  367. * @return void
  368. */
  369. public function getOrderInfo($ids)
  370. {
  371. $action = __FUNCTION__; // 请求资源名
  372. return $this->request($action, compact($ids), 'post');
  373. }
  374. /**
  375. * 获取订单详情
  376. *
  377. * @param int $id
  378. * @return array
  379. */
  380. public function orderDetail(int $id)
  381. {
  382. $action = __FUNCTION__; // 请求资源名
  383. return $this->request($action, compact('id'));
  384. }
  385. public function orderDetailByThirdOrderSn($order_no)
  386. {
  387. $action = __FUNCTION__; // 请求资源名
  388. return $this->request($action, ['third_order_sn' => $order_no]);
  389. }
  390. public function getAfterSalesTypeNameMap(int $order_id = 0, int $order_item_id = 0)
  391. {
  392. $action = __FUNCTION__; // 请求资源名
  393. $id = $order_id;
  394. $key = 'order_id';
  395. if (empty($id)) {
  396. $id = $order_item_id;
  397. $key = 'order_item_id';
  398. }
  399. if (empty($id)) throw new \Exception("中台订单id或中台子订单id必须选择一个");
  400. return $this->request($action, compact($key));
  401. }
  402. /**
  403. * @param int $id 中台售后id
  404. * @return array|bool
  405. */
  406. public function refundUserReceive(int $id)
  407. {
  408. $action = __FUNCTION__; // 请求资源名
  409. return $this->request($action, compact('id'), 'post');
  410. }
  411. /**
  412. * @param int $order_item_id
  413. * @return array|bool
  414. */
  415. public function getAfterSalesByOrderItemId(int $order_item_id)
  416. {
  417. $action = __FUNCTION__; // 请求资源名
  418. return $this->request($action, compact('order_item_id'));
  419. }
  420. /**
  421. * 请求
  422. *
  423. * @param string $method
  424. * @param string $action
  425. * @param array $param
  426. * @param boolean $is_data
  427. * @return boolean|array
  428. */
  429. private function request($action, $param = [], $method = 'get', $is_data = true)
  430. {
  431. $action = $this->api_list[$action] ?? '';
  432. if (empty($action)) {
  433. $this->error = "$action 对应API接口不存在";
  434. return false;
  435. }
  436. try {
  437. $host = $this->app_host ?: self::API_RUL;
  438. $result = $this->curl_request($host . $action, $param, $method);
  439. if (!isset($result['code']) || $result['code'] != '0') {
  440. $msg = $result['msg'] ?? '未知错误' . __LINE__;
  441. if (isset($result['data']['messages'][0])) {
  442. $msg = $result['data']['messages'][0];
  443. }
  444. $this->error = $msg;
  445. throw new \Exception($msg);
  446. }
  447. if ($is_data && !isset($result['data'])) {
  448. $this->error = "请求{$action}接口失败:未返回data数据";
  449. return false;
  450. }
  451. return $is_data ? $result['data'] : $result;
  452. } catch (\Exception $e) {
  453. \Yii::error($e->getMessage());
  454. $this->error = $e->getMessage();
  455. }
  456. return false;
  457. }
  458. /**
  459. * 发送curl请求
  460. *
  461. * @param string $url
  462. * @param array $data
  463. * @param string $method
  464. * @return array
  465. */
  466. private function curl_request($url, $data = [], $method = 'get')
  467. {
  468. if ($method == 'get' && !empty($data)) {
  469. $str = http_build_query($data);
  470. $url = strpos($url, '?') === false ? $url . '?' . $str : $url . '&' . $str;
  471. }
  472. $headers = [
  473. "Content-type: application/json",
  474. "charset=utf-8",
  475. "Accept: application/json",
  476. ];
  477. if (!empty($this->token)) {
  478. $headers[] = "x-token: " . $this->token;
  479. }
  480. $curl = curl_init();
  481. $timeout = 5;
  482. curl_setopt($curl, CURLOPT_URL, $url);
  483. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
  484. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  485. curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
  486. curl_setopt($curl, CURLOPT_TIMEOUT, 10); // 添加超时无响应
  487. if ($method == 'post') {
  488. curl_setopt($curl, CURLOPT_POST, 1);
  489. curl_setopt($curl, CURLOPT_POSTFIELDS, Json::encode($data));
  490. }
  491. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  492. $curl_data = curl_exec($curl);
  493. if (curl_error($curl)) {
  494. $error = '错误:' . $url . '=>' . curl_error($curl);
  495. throw new \Exception($error);
  496. }
  497. \Yii::$app->custom->logs(sprintf('请求地址: %s', $url));
  498. \Yii::$app->custom->logs(sprintf('请求信息: %s', json_encode($data)));
  499. \Yii::$app->custom->logs(sprintf('响应信息: %s', json_encode($curl_data)));
  500. return Json::decode($curl_data);
  501. }
  502. }