KeloopForm.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models\keloop;
  8. use app\models\Option;
  9. use app\constants\OptionSetting;
  10. use app\models\AccountLog;
  11. use app\models\User;
  12. use app\models\SaasUser;
  13. use app\models\Cat;
  14. use app\models\Goods;
  15. use app\models\Supplier;
  16. use app\models\Attr;
  17. use app\models\AttrGroup;
  18. use app\modules\admin\models\GoodsForm;
  19. use app\models\GoodsCat;
  20. use app\models\Order;
  21. use app\models\OrderDetail;
  22. use app\models\Store;
  23. use app\models\common\CommonOrder;
  24. use app\modules\client\models\v1\BindForm;
  25. use app\modules\client\models\v1\ShareMoneyForm;
  26. use app\modules\client\models\OrderComplete;
  27. use app\models\UserShareLog;
  28. use app\models\Share;
  29. use app\models\UserShareMoney;
  30. use app\models\UserBindLog;
  31. use app\models\Level;
  32. use zmoyi\JuShuiTan\Auth\Auth;
  33. use zmoyi\JuShuiTan\Api\ApiRequest;
  34. use zmoyi\JuShuiTan\Api\Common\ServeHttp;
  35. use zmoyi\JuShuiTan\Api\Common\Util;
  36. use app\modules\admin\models\SupplierForm;
  37. use app\modules\admin\models\PlatformForm;
  38. use app\utils\Keloop\Keloop;
  39. use app\models\DeliveryInfo;
  40. use app\models\DeliveryKeloop;
  41. use app\models\DeliveryKeloopErr;
  42. use app\modules\admin\models\OrderListForm;
  43. class KeloopForm extends Model
  44. {
  45. public static $confs = [];
  46. public $store_id;
  47. const DELIVERY_STATUS_WAIT_CREATE = '1';
  48. const DELIVERY_STATUS_WAIT_HOLD = '2';
  49. const DELIVERY_STATUS_DELIVERY = '3';
  50. const DELIVERY_STATUS_PICKUP = '4';
  51. const DELIVERY_STATUS_DELIVERING = '5';
  52. const DELIVERY_STATUS_DONE = '6';
  53. const DELIVERY_STATUS_CANCEL = '7';
  54. const DELIVERY_STATUS_IN_STORE = '9';
  55. public static $order_status_list = [
  56. self::DELIVERY_STATUS_WAIT_CREATE => '待发单',
  57. self::DELIVERY_STATUS_WAIT_HOLD => '待抢单',
  58. self::DELIVERY_STATUS_DELIVERY => '待接单',
  59. self::DELIVERY_STATUS_PICKUP => '取单中',
  60. self::DELIVERY_STATUS_DELIVERING => '送单中',
  61. self::DELIVERY_STATUS_DONE => '已送达',
  62. self::DELIVERY_STATUS_CANCEL => '已撤销',
  63. self::DELIVERY_STATUS_IN_STORE => '骑手到店',
  64. ];
  65. public static function callbackCommand($command, array $data){
  66. debug_log([__FUNCTION__, __LINE__, $command, $data], __CLASS__ . '.log');
  67. $command = 'cb_' . $command;
  68. if($data['data']){
  69. $data = json_decode($data['data'], true);
  70. }
  71. $res = call_user_func_array([new KeloopCallback(), $command], [$data]);
  72. if($res['code'] === 0){
  73. $res['code'] = 200;
  74. }
  75. debug_log([__FUNCTION__, __LINE__, $command, $res], __CLASS__ . '.log');
  76. return $res;
  77. }
  78. public static function saasConf(){
  79. $conf = json_decode(Option::get(OptionSetting::KELOOP, 0, 'saas', '{}')['value'], true);
  80. if(!$conf){
  81. $conf = [
  82. 'dev_key' => '',
  83. 'dev_secret' => '',
  84. 'team_token' => '',
  85. ];
  86. }
  87. $url_callback = '';
  88. if (\Yii::$app instanceof \yii\web\Application){
  89. $url_callback = \Yii::$app->request->hostInfo . '/index.php/keloop/callback/index';
  90. }
  91. return [
  92. 'code'=>0,
  93. 'msg'=>'ok',
  94. 'data' => $conf,
  95. 'url_callback' => $url_callback,
  96. 'openLink' => 'https://open.keloop.cn/',
  97. 'adminLink' => 'https://admin.keloop.cn/',
  98. 'docLink' => 'https://apifox.com/apidoc/shared-a4e1709f-0728-4224-908e-35eb12bc2959/doc-1988267',
  99. ];
  100. }
  101. public static function saasConfSave($conf){
  102. if(!is_array($conf)){
  103. $conf = json_decode($conf, true);
  104. }
  105. Option::set(OptionSetting::KELOOP, json_encode($conf), 0, 'saas');
  106. return [
  107. 'code'=>0,
  108. 'msg'=>'保存成功'
  109. ];
  110. }
  111. public static function isSaasOpen() {
  112. $conf = self::saasConf();
  113. return empty($conf['data']['dev_key']) ? 0 : 1;
  114. }
  115. public static function conf($store_id = 0, $refresh = 0) {
  116. $cacheK = $store_id;
  117. if(isset(self::$confs[$cacheK]) && !$refresh){
  118. return self::$confs[$cacheK];
  119. }
  120. $conf = json_decode(Option::get(OptionSetting::KELOOP_TOKEN, $store_id, 'store', '{}')['value'], true);
  121. if(!$conf){
  122. $conf = [
  123. "shop_name" => "", //店铺名称
  124. "shop_tel" => "", //店铺电话
  125. "shop_address" => "", //店铺地址
  126. "shop_tag" => "", //店铺坐标,火星坐标,如:116.459226,40.007126
  127. 'meal_assessment_time' => '10', //出餐时间(分钟)
  128. ];
  129. }
  130. self::$confs[$cacheK] = $conf;
  131. return $conf;
  132. }
  133. public static function saveConf($store_id = 0, $config = [], &$createMerchant = []) {
  134. $oldConf = self::conf($store_id, 1);
  135. $conf = array_merge($oldConf, $config);
  136. $createMerchant = self::createMerchant($store_id, $conf);
  137. if($createMerchant['code']){
  138. return $createMerchant;
  139. }
  140. $set = Option::set(OptionSetting::KELOOP_TOKEN, json_encode($conf), $store_id, 'store');
  141. self::conf($store_id, 1);
  142. return $set;
  143. }
  144. public static function getConf($store_id = 0, $key = '') {
  145. $config = self::conf($store_id);
  146. return $config[$key];
  147. }
  148. public static function setConf($store_id = 0, $key = '', $val = '') {
  149. $config = self::conf($store_id);
  150. $config[$key] = $val;
  151. return self::saveConf($store_id, $config);
  152. }
  153. public static function apiConf($store_id = 0) {
  154. $conf = self::saasConf()['data'];
  155. return $conf;
  156. }
  157. public static function apiRes($apiRes) {
  158. $res = [
  159. 'code' => 1,
  160. 'msg' => '操作失败。',
  161. ];
  162. if($apiRes['code'] == 200){
  163. $res = [
  164. 'code' => 0,
  165. 'msg' => '操作成功.',
  166. ];
  167. }
  168. $res['msg'] = $apiRes['message'];
  169. $res['data'] = $apiRes['data'];
  170. // $res['_data'] = $apiRes;
  171. //api_err字符串可用于筛选错误
  172. $res['code'] && debug_log([__FUNCTION__, 'api_err', $apiRes], __CLASS__ . '.log');
  173. return $res;
  174. }
  175. public static function apiErrs($n = 200) {
  176. $err = [];
  177. try{
  178. $file_path = \Yii::$app->runtimePath . '/logs/app_modules_admin_models_keloop_KeloopForm.log';
  179. if(file_exists($file_path)){
  180. $fp = fopen($file_path,"r");
  181. $pos=-2;
  182. $eof="";
  183. while($n>0){
  184. while($eof != "\n"){
  185. if(!fseek($fp, $pos, SEEK_END)){
  186. $eof = fgetc($fp);
  187. $pos--;
  188. }else{
  189. break;
  190. }
  191. }
  192. $line = fgets($fp, 1000);
  193. if(strstr($line, 'api_err')){
  194. $err[] = $line;
  195. }
  196. $eof="";
  197. $n--;
  198. }
  199. }
  200. } catch (\Exception $ex) {
  201. $err[] = $ex->getMessage();
  202. }
  203. return $err;
  204. }
  205. public static function sdk($store_id = 0) {
  206. return Keloop::app(self::apiConf($store_id));
  207. }
  208. public static function getTeamInfo($store_id) {
  209. try{
  210. return self::apiRes(self::sdk($store_id)->getTeamInfo());
  211. } catch (\Exception $ex) {
  212. return [
  213. 'code' => 1,
  214. 'msg' => $ex->getMessage(),
  215. ];
  216. }
  217. }
  218. public static function getCouriers($store_id) {
  219. try{
  220. return self::apiRes(self::sdk($store_id)->getCouriers());
  221. } catch (\Exception $ex) {
  222. return [
  223. 'code' => 1,
  224. 'msg' => $ex->getMessage(),
  225. ];
  226. }
  227. }
  228. public static function getMerchants($store_id) {
  229. try{
  230. return self::apiRes(self::sdk($store_id)->getMerchants());
  231. } catch (\Exception $ex) {
  232. return [
  233. 'code' => 1,
  234. 'msg' => $ex->getMessage(),
  235. ];
  236. }
  237. }
  238. public static function getCourierTag($store_id, $trade_no) {
  239. try{
  240. return self::apiRes(self::sdk($store_id)->getCourierTag(['trade_no' => $trade_no]));
  241. } catch (\Exception $ex) {
  242. return [
  243. 'code' => 1,
  244. 'msg' => $ex->getMessage(),
  245. ];
  246. }
  247. }
  248. public static function getOrderInfo($store_id, $trade_no, $change_data = 1) {
  249. try{
  250. $res = self::apiRes(self::sdk($store_id)->getOrderInfo(['trade_no' => $trade_no]));
  251. } catch (\Exception $ex) {
  252. return [
  253. 'code' => 1,
  254. 'msg' => $ex->getMessage(),
  255. ];
  256. }
  257. $change_data && self::data_delivery_change($store_id, $trade_no, [], $res);
  258. return $res;
  259. }
  260. public static function getOrderLog($store_id, $trade_no) {
  261. try{
  262. return self::apiRes(self::sdk($store_id)->getOrderLog(['trade_no' => $trade_no]));
  263. } catch (\Exception $ex) {
  264. return [
  265. 'code' => 1,
  266. 'msg' => $ex->getMessage(),
  267. ];
  268. }
  269. }
  270. public static function mealOutOrder($store_id, $trade_no, $time = 0) {
  271. $conf = self::conf($store_id);
  272. $param = [
  273. 'trade_no' => $trade_no,
  274. 'meal_assessment_time' => time() + 60 * $conf['meal_assessment_time'],
  275. ];
  276. if($time){
  277. $param['meal_assessment_time'] = $time;
  278. }
  279. try{
  280. return self::apiRes(self::sdk($store_id)->mealOutOrder($param));
  281. } catch (\Exception $ex) {
  282. return [
  283. 'code' => 1,
  284. 'msg' => $ex->getMessage(),
  285. ];
  286. }
  287. }
  288. public static function createMerchant($store_id, $conf = []) {
  289. $cancelMerchantRelate = self::cancelMerchantRelate($store_id);
  290. if($cancelMerchantRelate['code']){
  291. return $cancelMerchantRelate;
  292. }
  293. empty($conf) && $conf = self::conf($store_id);
  294. $params = [
  295. "shop_id" => $store_id,
  296. "shop_name" => $conf['shop_name'], //店铺名称
  297. "shop_tel" => $conf['shop_tel'], //店铺电话
  298. "shop_address" => $conf['shop_address'], //店铺地址
  299. "shop_tag" => $conf['shop_tag'], //店铺坐标,火星坐标,如:116.459226,40.007126
  300. ];
  301. try{
  302. return self::apiRes(self::sdk($store_id)->createMerchant($params));
  303. } catch (\Exception $ex) {
  304. return [
  305. 'code' => 1,
  306. 'msg' => $ex->getMessage(),
  307. ];
  308. }
  309. }
  310. public static function getFundUrl($store_id) {
  311. $params = [
  312. "shop_id" => $store_id,
  313. ];
  314. try{
  315. return self::apiRes(self::sdk($store_id)->getFundUrl($params));
  316. } catch (\Exception $ex) {
  317. return [
  318. 'code' => 1,
  319. 'msg' => $ex->getMessage(),
  320. ];
  321. }
  322. }
  323. public static function cancelMerchantRelate($store_id) {
  324. $params = [
  325. "shop_id" => $store_id,
  326. ];
  327. try{
  328. return self::apiRes(self::sdk($store_id)->cancelMerchantRelate($params));
  329. } catch (\Exception $ex) {
  330. return [
  331. 'code' => 1,
  332. 'msg' => $ex->getMessage(),
  333. ];
  334. }
  335. }
  336. public static function getFee($store_id, $lng, $lat) {
  337. $customer_tag = implode(',', [$lng, $lat]);
  338. $conf = self::conf($store_id);
  339. $params = [
  340. "shop_id" => $store_id,
  341. "get_tag" => $conf['shop_tag'],
  342. "customer_tag" => $customer_tag,
  343. "order_price" => 10, //$order['pay_price'],
  344. ];
  345. try{
  346. return self::apiRes(self::sdk($store_id)->getFee($params));
  347. } catch (\Exception $ex) {
  348. return [
  349. 'code' => 1,
  350. 'msg' => $ex->getMessage(),
  351. ];
  352. }
  353. }
  354. public static function preAddOrder($store_id, $order_no, $lng, $lat) {
  355. if (!$order_no) {
  356. return [
  357. 'code' => 1,
  358. 'msg' => '缺少订单号参数'
  359. ];
  360. }
  361. $fee = self::getFee($store_id, $lng, $lat);
  362. if ($fee['code']) {
  363. return $fee;
  364. }
  365. $freight = $fee['data']['pay_fee'];
  366. DeliveryInfo::deleteAll(['order_no' => $order_no, 'store_id' => $store_id, 'status' => 0]);
  367. $delivery_info = new DeliveryInfo();
  368. $delivery_info->store_id = $store_id;
  369. $delivery_info->order_no = $order_no;
  370. $delivery_info->delivery_type = '';
  371. $delivery_info->fee = $freight;
  372. $delivery_info->created_at = time();
  373. $save = $delivery_info->save();
  374. if(!$save){
  375. return [
  376. 'code' => 1,
  377. 'msg' => array_shift($delivery_info->getFirstErrors()),
  378. ];
  379. }
  380. return [
  381. 'code' => 0,
  382. 'msg' => 'ok',
  383. 'data' => [
  384. "resultcode" => 0,
  385. 'fee' => (float)$delivery_info->fee,
  386. 'fee_data' => $fee,
  387. ],
  388. ];
  389. }
  390. public static function order_created($store_id, $order_id = 0, $saveErr = 1){
  391. try{
  392. $order = Order::findOne($order_id);
  393. if(!$order){
  394. return [
  395. 'code' => 1,
  396. 'msg' => '订单信息错误',
  397. ];
  398. }
  399. $delivery = DeliveryKeloop::findOne(['order_no' => $order->order_no, 'store_id' => $store_id]);
  400. if($delivery){
  401. return [
  402. 'code' => 1,
  403. 'msg' => '订单信息已存在',
  404. ];
  405. }
  406. $params = self::getOrder($store_id, $order);
  407. try{
  408. $res = self::apiRes(self::sdk($store_id)->createOrder($params));
  409. } catch (\Exception $ex) {
  410. return [
  411. 'code' => 1,
  412. 'msg' => $ex->getMessage(),
  413. ];
  414. }
  415. if($res['code']){
  416. if($saveErr){
  417. DeliveryKeloopErr::saveErr($store_id, $order->id, $order->order_no, $res);
  418. }
  419. return $res;
  420. }else{
  421. DeliveryKeloopErr::updateAll(['is_delete' => 1], ['order_no' => $order->order_no, 'store_id' => $store_id]);
  422. }
  423. self::data_order_created($store_id, $order, $res['data']);
  424. self::mealOutOrder($store_id, $res['data']['trade_no']);
  425. return $res;
  426. } catch (\Exception $ex) {
  427. \Yii::error([__METHOD__, $ex]);
  428. return [
  429. 'code' => 1,
  430. 'msg' => $ex->getMessage(),
  431. ];
  432. }
  433. }
  434. public static function data_order_created($store_id, $order, $data){
  435. $delivery = new DeliveryKeloop();
  436. $delivery->store_id = $store_id;
  437. $delivery->order_no = $order->order_no;
  438. $delivery->trade_no = $data['trade_no'];
  439. $delivery->fee = $data['pay_fee'];
  440. $delivery->delivery_status = self::DELIVERY_STATUS_DELIVERY;
  441. $save = $delivery->save();
  442. if(!$save){
  443. return [
  444. 'code' => 1,
  445. 'msg' => array_shift($delivery->getFirstErrors()),
  446. ];
  447. }
  448. if($order->trade_status < Order::ORDER_FLOW_SEND){
  449. $order->trade_status = Order::ORDER_FLOW_SEND;
  450. $order->send_time = time();
  451. if (!$order->save()) {
  452. debug_log([__FUNCTION__, __LINE__, '订单发货失败', array_shift($order->getFirstErrors())], __CLASS__ . '.log');
  453. return [
  454. 'code' => 1,
  455. 'msg' => '订单发货失败',
  456. ];
  457. }
  458. }
  459. return [
  460. 'code' => 0,
  461. 'msg' => 'ok',
  462. ];
  463. }
  464. public static function getOrder($store_id, $order) {
  465. $address_data = json_decode($order->address_data, true);
  466. $conf = self::conf($store_id);
  467. $data = [
  468. "shop_id" => $store_id,
  469. "shop_name" => $conf['shop_name'], //店铺名称
  470. "shop_tel" => $conf['shop_tel'], //店铺电话
  471. "shop_address" => $conf['shop_address'], //店铺地址
  472. "shop_tag" => $conf['shop_tag'], //店铺坐标,火星坐标,如:116.459226,40.007126
  473. // "store_id" => $md_id,
  474. 'order_mark' => $order->food_code,
  475. 'order_time' => date('Y-m-d H:i:s', $order->created_at),
  476. 'customer_tel' => $order->mobile,
  477. 'customer_address' => $order->address,
  478. 'customer_name' => $order->name,
  479. 'customer_tag' => implode(',', [$address_data['longitude'] ?? '', $address_data['latitude'] ?? '']),
  480. "order_no" => $order->order_no,
  481. 'pay_status' => 0,
  482. // 'pre_times' => $delivery_time,
  483. // 'pre_deliver_times' => $delivery_time,
  484. ];
  485. if(!empty($order->delivery_time)){
  486. $delivery_time = $order->delivery_time;
  487. $data['pre_times'] = $delivery_time;
  488. $data['pre_deliver_times'] = $delivery_time;
  489. }
  490. return $data;
  491. }
  492. /**
  493. * 订单取消
  494. * @param type $store_id
  495. * @param type $order_id
  496. * @param type $reason
  497. * @param type $reason_code //取消类型 1用户 2商户 3客服 4系统 5其他
  498. */
  499. public static function order_canceled($store_id, $order_id = 0, $reason = '取消', $reason_code = 1){
  500. try{
  501. $order = Order::findOne($order_id);
  502. if(!$order){
  503. return [
  504. 'code' => 1,
  505. 'msg' => '订单信息错误',
  506. ];
  507. }
  508. $delivery = DeliveryKeloop::findOne(['order_no' => $order['order_no'], 'store_id' => $store_id]);
  509. if(!$delivery){
  510. return [
  511. 'code' => 1,
  512. 'msg' => '配送单信息错误',
  513. ];
  514. }
  515. $params = [
  516. 'reason' => (string)$reason,
  517. 'trade_no' => $delivery['trade_no'],
  518. ];
  519. try{
  520. $res = self::apiRes(self::sdk($store_id)->cancelOrder($params));
  521. } catch (\Exception $ex) {
  522. return [
  523. 'code' => 1,
  524. 'msg' => $ex->getMessage(),
  525. ];
  526. }
  527. if($res['code'] != 0){
  528. return $res;
  529. }
  530. self::data_order_canceled($store_id, $order->order_no, $params);
  531. return $res;
  532. } catch (\Exception $ex) {
  533. return [
  534. 'code' => 1,
  535. 'msg' => $ex->getMessage(),
  536. ];
  537. }
  538. }
  539. public static function data_order_canceled($store_id, $order_no = '', $params = []){
  540. $delivery = DeliveryKeloop::findOne(['order_no' => $order_no, 'store_id' => $store_id]);
  541. $delivery->is_cancel = 1;
  542. $params['reason'] && $delivery->cancel_reason = $params['reason'];
  543. $save = $delivery->save();
  544. if(!$save){
  545. return [
  546. 'code' => 1,
  547. 'msg' => array_shift($delivery->getFirstErrors()),
  548. ];
  549. }
  550. return [
  551. 'code' => 0,
  552. 'msg' => 'ok',
  553. ];
  554. }
  555. public static function afterOrderSave($insert, $changedAttributes, $order){
  556. try{
  557. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $order->store_id, 'store')['value'];
  558. $local_type = Option::get(OptionSetting::STORE_LOCAL_TYPE, $order->store_id, 'pay', $local_type)['value'];
  559. \Yii::error($local_type);
  560. if($local_type != 'keloop'){
  561. return;
  562. }
  563. //取消订单
  564. if (($order->is_delivery == 1) &&
  565. ($order->trade_status == Order::ORDER_FLOW_CANCEL) &&
  566. ($changedAttributes['trade_status'] != Order::ORDER_FLOW_CANCEL)) {
  567. $delivery = DeliveryKeloop::findOne(['order_no' => $order->order_no, 'store_id' => $order->store_id]);
  568. if($delivery){
  569. $order_canceled = self::order_canceled($order->store_id, $order->id);
  570. if($order_canceled['code'] !== 0){
  571. throw new \Exception($order_canceled['msg']);
  572. }
  573. }
  574. }
  575. } catch (\Exception $ex) {
  576. \Yii::error($ex);
  577. debug_log([__FUNCTION__, __LINE__, $ex->getMessage(), $ex->getTrace()], __CLASS__ . '.log');
  578. }
  579. }
  580. public static function data_delivery_change($store_id, $trade_no = '', $callback_data = [], $orderInfo = []){
  581. if($callback_data['sign'] && cache_lock(['keloop_callback', $callback_data['sign']], 86400)){
  582. return;
  583. }
  584. $delivery = DeliveryKeloop::findOne(['trade_no' => $trade_no, 'store_id' => $store_id]);
  585. if(!$delivery){
  586. return;
  587. }
  588. $orderInfo || $orderInfo = self::getOrderInfo($store_id, $trade_no, 0);
  589. if($orderInfo['code']){
  590. return;
  591. }
  592. $delivery->delivery_status = $orderInfo['data']['status'];
  593. $delivery->rider_name = $orderInfo['data']['courier_name'];
  594. $delivery->rider_mobile = $orderInfo['data']['courier_tel'];
  595. $ctag = self::getCourierTag($store_id, $trade_no);
  596. if(!$ctag['code']){
  597. $delivery->lng = $ctag['data']['longitude'];
  598. $delivery->lat = $ctag['data']['latitude'];
  599. }
  600. $save = $delivery->save();
  601. if(!$save){
  602. return [
  603. 'code' => 1,
  604. 'msg' => array_shift($delivery->getFirstErrors()),
  605. ];
  606. }
  607. if($delivery->delivery_status == self::DELIVERY_STATUS_DONE){
  608. debug_log([__FUNCTION__, __LINE__, '确认收货', $delivery->delivery_status], __CLASS__ . '.log');
  609. //确认收货
  610. $order = Order::find()->where(['order_no' => $delivery->order_no])->andWhere(['trade_status' => Order::ORDER_FLOW_SEND])->one();
  611. if(!$order){
  612. return [
  613. 'code' => 1,
  614. 'msg' => '确认收货订单状态信息错误',
  615. ];
  616. }
  617. $order->trade_status = Order::ORDER_FLOW_CONFIRM;
  618. $order->confirm_time = time();
  619. if (!$order->save()) {
  620. debug_log([__FUNCTION__, __LINE__, '确认收货失败', array_shift($order->getFirstErrors())], __CLASS__ . '.log');
  621. return [
  622. 'code' => 1,
  623. 'msg' => '确认收货失败',
  624. ];
  625. }
  626. }
  627. return [
  628. 'code' => 0,
  629. 'msg' => 'ok',
  630. ];
  631. }
  632. public static function orderList($store_id, $params){
  633. $form = new OrderListForm();
  634. if($params['dateEnd']){
  635. $params['dateEnd'] .= ' 23:59:59';
  636. }
  637. $form->attributes = $params;
  638. $form->store_id = $store_id;
  639. $form->keloop = 1;
  640. $form->mch = -1;
  641. $form->is_delivery = true;
  642. $list = $form->search();
  643. unset($list['data']['export_list']);
  644. unset($list['data']['express_list']);
  645. foreach($list['data']['data'] as &$item){
  646. $deliveryModel = DeliveryKeloop::findOne(['order_no' => $item['order_no']]);
  647. $delivery = $deliveryModel->attributes;
  648. $delivery['delivery_status_name'] = self::$order_status_list[$delivery['delivery_status']] ?? '';
  649. $keloopOrderInfo = self::getOrderInfo($store_id, $delivery['trade_no']);
  650. if(!$keloopOrderInfo['code']){
  651. $delivery['delivery_status_name'] = self::$order_status_list[$keloopOrderInfo['data']['status']] ?? '';
  652. }
  653. $item['delivery'] = $delivery;
  654. $item['keloopOrderInfo'] = $keloopOrderInfo;
  655. }
  656. $list['keloop'] = [
  657. 'delivery_status_list' => self::$order_status_list,
  658. ];
  659. return $list;
  660. }
  661. public static function orderErrList($store_id){
  662. $list = DeliveryKeloopErr::find()->where(['store_id' => $store_id, 'is_delete' => 0])->orderBy('id DESC')->all();
  663. return [
  664. 'code' => 0,
  665. 'data' => $list,
  666. ];
  667. }
  668. public static function orderErrRecreate($store_id, $id){
  669. $err = DeliveryKeloopErr::findOne(['store_id' => $store_id, 'id' => $id, 'is_delete' => 0]);
  670. if(!$err){
  671. return [
  672. 'code' => 1,
  673. 'msg' => '订单不存在,或配送单正常'
  674. ];
  675. }
  676. $delivery_res = KeloopForm::order_created($store_id, $err['order_id'], 0);
  677. return $delivery_res;
  678. }
  679. public static function orderFee($store_id, $order_id){
  680. $order = Order::findOne(['store_id' => $store_id, 'id' => $order_id]);
  681. $addr = json_decode($order->address_data, true);
  682. $getFee = KeloopForm::getFee($store_id, $addr['longitude'], $addr['latitude']);
  683. return $getFee;
  684. }
  685. }