DriverForm.php 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242
  1. <?php
  2. /**
  3. * 重庆赤晓店信息科技有限公司
  4. * https://www.chixiaodian.com
  5. * Copyright (c) 2023 赤店商城 All rights reserved.
  6. */
  7. namespace app\modules\admin\models;
  8. use app\models\Admin;
  9. use app\models\AgentFrontBind;
  10. use app\models\AgentFrontCentralizeGoods;
  11. use app\models\AgentFrontCentralizeGoodsCancelLog;
  12. use app\models\AgentFrontCentralizeGoodsExt;
  13. use app\models\AgentFrontStaff;
  14. use app\models\AgentFrontStaffOperateLog;
  15. use app\models\District;
  16. use app\models\DriverMdBind;
  17. use app\models\Md;
  18. use app\models\Option;
  19. use app\models\StoreCloud;
  20. use yii\base\Model;
  21. use app\models\Store;
  22. use app\models\SaasUser;
  23. use app\models\Driver;
  24. use app\models\DriverLine;
  25. use app\models\DriverLineOrder;
  26. class DriverForm extends Model
  27. {
  28. public $page = 1;
  29. public $limit = 10;
  30. public $id;
  31. public $line_name;
  32. public $name;
  33. public $tel;
  34. public $car_no;
  35. public $admin_id;
  36. public $status;
  37. public $md_id;
  38. public $driver_id;
  39. public $open_status;
  40. public $ids;
  41. public $goods_num;
  42. public $car_loading_pic;
  43. public $goods_no;
  44. public $goods_name;
  45. public $is_car_loading;
  46. public $sortkey;
  47. public $params;
  48. public $type;
  49. public function rules()
  50. {
  51. return [
  52. [['id', 'md_id', 'driver_id', 'open_status', 'goods_num', 'is_car_loading', 'sortkey', 'type'], 'integer'],
  53. [['tel', 'name', 'ids', 'goods_no', 'goods_name', 'car_loading_pic', 'params'], 'string']
  54. ];
  55. }
  56. public function driverList() {
  57. $query = Driver::find()->where(['admin_id' => $this->admin_id, 'is_delete' => 0]);
  58. if($this->name){
  59. $query->andWhere(['like', 'name', $this->name]);
  60. }
  61. if($this->car_no){
  62. $query->andWhere(['car_no' => $this->car_no]);
  63. }
  64. if($this->tel){
  65. $saasUser = SaasUser::findOne(['mobile' => $this->tel, 'is_delete' => 0]);
  66. if($saasUser){
  67. $query->andWhere(['saas_user_id' => $saasUser->id]);
  68. }
  69. }
  70. $query->orderBy('id desc');
  71. $res = pagination_make($query);
  72. foreach ($res['list'] as &$item) {
  73. $saas_user_id = $item['saas_user_id'] ?? 0;
  74. $saas_user = SaasUser::findOne($saas_user_id);
  75. $item['saas_user'] = $saas_user ?? [
  76. 'name' => ''
  77. ];
  78. $item['md_count'] = DriverMdBind::find()->where(['driver_id' => $item['id'], 'is_delete' => 0])->select('md_id')->count();
  79. }
  80. $res['tencent_map_key'] = Option::get('tencent_map_key', 0, 'saas', '')['value'];
  81. return [
  82. 'code' => 0,
  83. 'msg' => 'success',
  84. 'data' => $res,
  85. ];
  86. }
  87. public function driverSave($id, $admin_id, $saas_user_id, $name, $car_no, $tel, $line_name, $area = [], $status = 1) {
  88. try{
  89. if(empty($admin_id)){
  90. throw new \Exception('代理用户不能为空');
  91. }
  92. // if(!is_array($area) || empty($area)){
  93. // throw new \Exception('区域格式不正确');
  94. // }
  95. if(empty($saas_user_id)){
  96. throw new \Exception('绑定用户不能为空');
  97. }
  98. $model = $id ? Driver::findOne($id) : new Driver();
  99. $model->admin_id = $admin_id;
  100. $model->saas_user_id = $saas_user_id;
  101. $model->name = $name;
  102. $model->car_no = $car_no;
  103. $model->tel = $tel;
  104. $model->line_name = $line_name;
  105. $model->area = json_encode($area);
  106. $model->status = $status;
  107. $save = $model->save();
  108. if(!$save){
  109. throw new \Exception('操作失败,' . array_shift($model->getFirstErrors()));
  110. }
  111. return [
  112. 'code' => 0,
  113. 'msg' => '操作成功',
  114. ];
  115. }catch(\Exception $e){
  116. \Yii::error([__METHOD__, $e]);
  117. return [
  118. 'code' => 1,
  119. 'msg' => $e->getMessage(),
  120. ];
  121. }
  122. }
  123. public function driverStatus ($ids, $status)
  124. {
  125. try {
  126. if ($ids) {
  127. is_string($ids) && $ids = explode(',', $ids);
  128. if (in_array($status, [0, 1])) {
  129. Driver::updateAll(['status' => $status], ['and', ['in', 'id', $ids], ['is_delete' => 0]]);
  130. }
  131. if ((int)$status === 2) {
  132. Driver::updateAll(['is_delete' => 1], ['and', ['in', 'id', $ids], ['is_delete' => 0]]);
  133. }
  134. }
  135. return [
  136. 'code' => 0,
  137. 'msg' => '操作成功!'
  138. ];
  139. } catch (\Exception $e) {
  140. return [
  141. 'code' => 1,
  142. 'msg' => $e->getMessage()
  143. ];
  144. }
  145. }
  146. public function driverLineList() {
  147. $query = DriverLine::find()->alias('dl')->where(['dl.is_delete' => 0]);
  148. $query->leftJoin(['d' => Driver::tableName()], 'd.id=dl.driver_id');
  149. $query->andWhere(['d.admin_id' => $this->admin_id]);
  150. if($this->name){
  151. $query->andWhere(['like', 'd.name', $this->name]);
  152. }
  153. if($this->line_name){
  154. $query->andWhere(['like', 'd.line_name', $this->line_name]);
  155. }
  156. if($this->car_no){
  157. $query->andWhere(['d.car_no' => $this->car_no]);
  158. }
  159. if($this->is_car_loading !== null && in_array($this->is_car_loading, [0, 1])) {
  160. if (!$this->is_car_loading) {
  161. $query->andWhere(['dl.status' => DriverLine::STATUS_NOT_CAR_LOADING]);
  162. } else {
  163. $query->andWhere(['dl.status' => [
  164. DriverLine::STATUS_WAIT,
  165. DriverLine::STATUS_DOING,
  166. DriverLine::STATUS_FINISH
  167. ]]);
  168. }
  169. }
  170. if($this->status !== null && in_array($this->status, [
  171. DriverLine::STATUS_NOT_CAR_LOADING,
  172. DriverLine::STATUS_WAIT,
  173. DriverLine::STATUS_DOING,
  174. DriverLine::STATUS_FINISH
  175. ])){
  176. $query->andWhere(['dl.status' => $this->status]);
  177. }
  178. if($this->tel){
  179. $query->andWhere(['LIKE', 'd.tel', $this->tel]);
  180. }
  181. $query->select('dl.id, dl.status, dl.finish_time, dl.driver_id')->orderBy('dl.id desc');
  182. $res = pagination_make($query);
  183. foreach ($res['list'] as &$item) {
  184. $driver = Driver::findOne($item['driver_id']);
  185. $lineOrderCount = DriverLineOrder::find()->where(['line_id' => $item['id'], 'is_delete' => 0])->groupBy('md_id')->count() ?: 0;
  186. $saas_user_id = $driver['saas_user_id'] ?? 0;
  187. // $saas_user = SaasUser::findOne($saas_user_id);
  188. // $item['saas_user'] = $saas_user;
  189. $item['driver'] = [
  190. 'line_name' => $driver->line_name,
  191. 'name' => $driver->name,
  192. 'car_no' => $driver->car_no,
  193. 'tel' => $driver->tel
  194. ];
  195. $item['lineOrderCount'] = $lineOrderCount;
  196. $item['orderGoodsCount'] = DriverLineOrder::find()->where(['line_id' => $item['id'], 'is_delete' => 0])->count() ?: 0;
  197. }
  198. return [
  199. 'code' => 0,
  200. 'msg' => 'success',
  201. 'data' => $res,
  202. ];
  203. }
  204. public function driverLineInfo() {
  205. $driver_line = DriverLine::findOne($this->id);
  206. $driver = Driver::findOne($driver_line->driver_id);
  207. $driver_line_order = [];
  208. $driver_line_order1 = DriverLineOrder::find()->where(['line_id' => $driver_line->id, 'is_delete' => 0])->orderBy('sortkey, goods_name')->asArray()->all();
  209. foreach ($driver_line_order1 as $item) {
  210. if(isset($driver_line_order[$item['md_id']])){
  211. $has = 0;
  212. foreach($driver_line_order[$item['md_id']]['goods'] as &$order){
  213. if($order['goods_name'] == $item['goods_name'] && $order['goods_attr_name'] == $item['goods_attr_name']){
  214. $has = 1;
  215. $order['goods_num'] += $item['goods_num'];
  216. }
  217. }
  218. if(!$has){
  219. $driver_line_order[$item['md_id']]['goods'][] = $item;
  220. }
  221. }else{
  222. $driver_line_order[$item['md_id']] = $item;
  223. $driver_line_order[$item['md_id']]['goods'] = [$item];
  224. }
  225. $store_cloud = StoreCloud::findOne(['cloud_store_id' => $item['cloud_store_id'], 'is_delete' => 0]);
  226. $store = Store::findOne($store_cloud->store_id);
  227. $store_name = $store->name;
  228. if ($item['md_id'] > 0) {
  229. $mdInfo = Md::findOne($item['md_id']);
  230. $store_name = $mdInfo->name ?? $store_name;
  231. }
  232. $driver_line_order[$item['md_id']]['store_name'] = $store_name;
  233. }
  234. $driver_line_order = array_values($driver_line_order);
  235. $lineOrderCount = DriverLineOrder::find()->where(['line_id' => $driver_line->id, 'is_delete' => 0])->groupBy('cloud_store_id')->count();
  236. return [
  237. 'code' => 0,
  238. 'driver_line' => $driver_line,
  239. 'driver' => $driver,
  240. 'driver_line_order' => $driver_line_order,
  241. 'lineOrderCount' => $lineOrderCount,
  242. ];
  243. }
  244. //点击装车
  245. public function driverLineStart()
  246. {
  247. try {
  248. $driver_line = DriverLine::findOne($this->id);
  249. if (!$driver_line) {
  250. throw new \Exception('订单未找到');
  251. }
  252. if (intval($driver_line->status) !== DriverLine::STATUS_NOT_CAR_LOADING) {
  253. throw new \Exception('已经装车 请勿重复操作');
  254. }
  255. if (empty(trim($this->car_loading_pic))) {
  256. throw new \Exception('缺失装车图片');
  257. }
  258. $driver_line->status = DriverLine::STATUS_WAIT;
  259. $driver_line->car_loading_time = time();
  260. $driver_line->car_loading_pic = $this->car_loading_pic;
  261. if (!$driver_line->save()) {
  262. throw new \Exception(implode(';', array_values($driver_line->firstErrors)));
  263. }
  264. return [
  265. 'code' => 0,
  266. 'msg' => '操作成功',
  267. ];
  268. } catch (\Exception $e) {
  269. return [
  270. 'code' => 1,
  271. 'msg' => $e->getMessage(),
  272. ];
  273. }
  274. }
  275. //获取装车明细
  276. public function carLoadingDetail() {
  277. try {
  278. $id = $this->id;
  279. $driver_line = DriverLine::findOne($id);
  280. if (!$driver_line) {
  281. throw new \Exception('订单未找到');
  282. }
  283. $goods_name = $this->goods_name;
  284. $goods_no = $this->goods_no;
  285. $query = DriverLineOrder::find()->alias('dlo')
  286. ->leftJoin(['g' => AgentFrontCentralizeGoods::tableName()], 'dlo.centralize_goods_id = g.id')
  287. ->where(['dlo.line_id' => $id, 'dlo.is_delete' => 0, 'g.is_delete' => 0])->groupBy('dlo.centralize_goods_id');
  288. if (!empty(trim($goods_name))) {
  289. $query->andWhere(['LIKE', 'dlo.goods_name', trim($goods_name)]);
  290. }
  291. if (!empty(trim($goods_no))) {
  292. $query->andWhere(['LIKE', 'g.goods_no', trim($goods_no)]);
  293. }
  294. $query->select('dlo.id, dlo.goods_name, dlo.goods_attr_name, g.goods_no, g.centralize_goods_type,
  295. dlo.centralize_goods_id, g.pic_url, SUM(dlo.cancel_goods_num) as cancel_num')
  296. ->orderBy('dlo.id DESC');
  297. $list = pagination_make($query);
  298. foreach ($list['list'] as &$item) {
  299. $centralize_goods_ext_id_arr = DriverLineOrder::find()->where(['centralize_goods_id' => $item['centralize_goods_id'], 'line_id' => $id])
  300. ->select('centralize_goods_ext_id')->column();
  301. $agentFrontCentralizeGoodsExtArr = AgentFrontCentralizeGoodsExt::find()->where(['id' => $centralize_goods_ext_id_arr, 'is_delete' => 0])
  302. ->select('goods_num, sorting_num')->asArray()->all();
  303. $item['order_num'] = array_sum(array_column($agentFrontCentralizeGoodsExtArr, 'goods_num'));
  304. $item['sorting_num'] = array_sum(array_column($agentFrontCentralizeGoodsExtArr, 'sorting_num'));
  305. $item['centralize_goods_type'] = intval($item['centralize_goods_type']);
  306. }
  307. return [
  308. 'code' => 0,
  309. 'msg' => '',
  310. 'data' => $list
  311. ];
  312. } catch (\Exception $e) {
  313. return [
  314. 'code' => 1,
  315. 'msg' => $e->getMessage(),
  316. ];
  317. }
  318. }
  319. // //判断点是否在多边形区域内
  320. // public function inArea($x,$y,$arr)
  321. // {
  322. // //点的数量
  323. // $count = count($arr);
  324. // $n = 0; //点与线相交的个数
  325. // $bool = 0;//外
  326. // for ($i = 0, $j = $count - 1; $i < $count; $j = $i, $i++) {
  327. // //两个点一条线 取出两个连接点的定点
  328. // $px1 = $arr[$i][0];
  329. // $py1 = $arr[$i][1];
  330. // $px2 = $arr[$j][0];
  331. // $py2 = $arr[$j][1];
  332. // //$x的水平位置画射线
  333. // if($x>=$px1 || $x>= $px2)
  334. // {
  335. // //判断$y 是否在线的区域
  336. // if(($y>=$py1 && $y<=$py2) || ($y>=$py2 && $y<= $py1)){
  337. // if (($y == $py1 && $x == $px1) || ($y == $py2 && $x == $px2)) {
  338. //
  339. // #如果$x的值和点的坐标相同
  340. // $bool = 2;//在点上
  341. // return $bool;
  342. //
  343. // }else{
  344. // $px = $px1+($y-$py1)/($py2-$py1)*($px2-$px1) ;
  345. // if($px ==$x)
  346. // {
  347. // $bool = 3;//在线上
  348. // }elseif($px< $x){
  349. // $n++;
  350. // }
  351. //
  352. // }
  353. // }
  354. // }
  355. //
  356. // }
  357. // if ($n%2 != 0) {
  358. // $bool = 1;
  359. // }
  360. // return $bool;
  361. // }
  362. //获取商城匹配的线路
  363. public function getLocDriver($agent_id, $md_id) {
  364. try {
  365. $driverMdBind = DriverMdBind::findOne(['md_id' => $md_id, 'is_delete' => 0]);
  366. if (!$driverMdBind) {
  367. throw new \Exception('分拣订单的来源门店需要绑定线路');
  368. }
  369. $driver = Driver::findOne(['admin_id' => $agent_id, 'is_delete' => 0, 'id' => $driverMdBind->driver_id, 'status' => 1]);
  370. if ($driver) {
  371. return [
  372. 'code' => 0,
  373. 'driver' => $driver,
  374. ];
  375. }
  376. throw new \Exception('司机未绑定当前仓库');
  377. } catch (\Exception $e) {
  378. \Yii::error([__METHOD__, $e]);
  379. return [
  380. 'code' => 1,
  381. 'msg' => $e->getMessage()
  382. ];
  383. }
  384. }
  385. // public function getOrder($id) {
  386. //// $form = new SupplierForm();
  387. //// $form->id = $id;
  388. //// return $form->agentOrderDistributionList();
  389. // $form = new PlatformForm();
  390. // return $form->getSortingOrder($id);
  391. //
  392. //
  393. // }
  394. //分配异常列表
  395. public function getOrderToLineErrList($agent_id) {
  396. $line_orders = DriverLineOrder::find()->where(['agent_id' => $agent_id, 'line_id' => 0])->all();
  397. return [
  398. 'code' => 0,
  399. 'msg' => 'ok',
  400. 'data' => $line_orders,
  401. 'count' => count($line_orders),
  402. ];
  403. }
  404. //手动分配路线
  405. public function setOrderToLine($id, $driver_id, $attr = []) {
  406. try{
  407. $line_order = DriverLineOrder::findOne($id);
  408. foreach($attr as $at => $val){
  409. $line_order->$at = $val;
  410. }
  411. $driver = Driver::findOne($driver_id);
  412. $line = $this->getLine($line_order['cloud_store_id'], $driver);
  413. if($line){
  414. $line_order->line_id = $line->id;
  415. $line_order->line_no = $line->line_no;
  416. }
  417. $save = $line_order->save();
  418. if(!$save){
  419. throw new \Exception(array_shift($line_order->getFirstErrors()));
  420. }
  421. return [
  422. 'code' => 0,
  423. 'msg' => 'ok'
  424. ];
  425. } catch (\Exception $e) {
  426. \Yii::error([__METHOD__, $e]);
  427. return [
  428. 'code' => 1,
  429. 'msg' => $e->getMessage()
  430. ];
  431. }
  432. }
  433. //拣货
  434. public function orderToLine() {
  435. $t = \Yii::$app->db->beginTransaction();
  436. try {
  437. $params = $this->params;
  438. $agent_id = $this->admin_id;
  439. $type = $this->type; //0分拣 1提交进度不分拣
  440. // $goods_num = $this->goods_num;
  441. if (!$params) {
  442. throw new \Exception('分拣数据错误');
  443. }
  444. $params = json_decode($params, true);
  445. // if ($goods_num <= 0 && count($ids) == 1) {
  446. // throw new \Exception('分拣数量错误');
  447. // }
  448. $open = false;
  449. $self = new self();
  450. foreach($params as $params_item){
  451. // $orders = $self->getOrder($id);
  452. if ($params_item['num'] <= 0) {
  453. throw new \Exception('分拣数量错误');
  454. }
  455. $params_num = $params_item['num'];
  456. // $params_num = 0;
  457. //兼容传多个分拣商品ID 只传递一个数量 比如:[{"id": "72, 73", "num": 2}]
  458. $ids = explode(',', $params_item['id']);
  459. foreach ($ids as $id_item) {
  460. if ($params_item['num'] <= 0) {
  461. continue;
  462. }
  463. $agentFrontCentralizeGoodsExt = AgentFrontCentralizeGoodsExt::find()->where(['id' => $id_item, 'is_delete' => 0])
  464. ->select('id, centralize_goods_id, cloud_order_id, goods_num, md_id, sorting_num, status')->asArray()->one();
  465. if (!$agentFrontCentralizeGoodsExt) {
  466. throw new \Exception('分拣商品信息不存在');
  467. }
  468. if (intval($agentFrontCentralizeGoodsExt['status']) !== AgentFrontCentralizeGoodsExt::STATUS_WAIT_SORTING) {
  469. throw new \Exception('部分订单已分拣完成,请勿重复操作');
  470. }
  471. /**
  472. * ------------
  473. * 9
  474. * 3 0
  475. * 3 0
  476. * 3 0
  477. * -----------
  478. */
  479. if (count($ids) > 1) {
  480. $agentFrontCentralizeGoodsExtAll = AgentFrontCentralizeGoodsExt::find()->where(['id' => $ids])
  481. ->select('goods_num, sorting_num')->asArray()->all();
  482. $goods_num = array_sum(array_column($agentFrontCentralizeGoodsExtAll, 'goods_num'));//9
  483. $sorting_num = array_sum(array_column($agentFrontCentralizeGoodsExtAll, 'sorting_num'));//0
  484. if ($params_item['num'] > ($goods_num - $sorting_num)) {
  485. throw new \Exception('分拣数量大于剩余待分拣数量');
  486. }
  487. if ($params_item['num'] == ($goods_num - $sorting_num)) {// 9 == 9 6 == 9 - 3
  488. $params_item['num'] = null;
  489. } else {// 2 >= 2 + 0
  490. if ($params_item['num'] >= ($agentFrontCentralizeGoodsExt['goods_num'] - $agentFrontCentralizeGoodsExt['sorting_num'])) {//3 >= 2 - 0
  491. $params_item['num'] = ($agentFrontCentralizeGoodsExt['goods_num'] - $agentFrontCentralizeGoodsExt['sorting_num']);//2-0 = 2
  492. // $params_num -= $params_item['num'];//3 - 2 = 1
  493. }
  494. }
  495. // if (isset($params_num)) {
  496. // $params_item['num'] = $params_num;//4 - 2//
  497. // }
  498. } else {
  499. if ($params_item['num'] > ($agentFrontCentralizeGoodsExt['goods_num'] - $agentFrontCentralizeGoodsExt['sorting_num'])) {
  500. throw new \Exception('分拣数量大于剩余待分拣数量');
  501. }
  502. }
  503. $agentFrontCentralizeGoods = AgentFrontCentralizeGoods::findOne(['id' => $agentFrontCentralizeGoodsExt['centralize_goods_id'], 'is_delete' => 0, 'status' => AgentFrontCentralizeGoods::STATUS_SORTING]);
  504. if (!$agentFrontCentralizeGoods) {
  505. throw new \Exception('商品不存在');
  506. }
  507. $md = Md::findOne($agentFrontCentralizeGoodsExt['md_id']);
  508. if (empty($md)) {
  509. throw new \Exception('门店不存在' . $agentFrontCentralizeGoodsExt['md_id']);
  510. }
  511. $agentFrontCentralizeGoodsExt = AgentFrontCentralizeGoodsExt::findOne($agentFrontCentralizeGoodsExt['id']);
  512. //组装数据
  513. // $goods_num_arr = array_column($order_list_item['goods_list'], 'num');
  514. $mch = [
  515. 'md_id' => $agentFrontCentralizeGoodsExt->md_id,
  516. 'store_id' => $md->store_id,
  517. 'tel' => $md->mobile,
  518. 'name' => $md->name,
  519. 'goods_num' => $params_item['num'] ?? ($agentFrontCentralizeGoodsExt->goods_num - $agentFrontCentralizeGoodsExt->sorting_num),
  520. ];
  521. $params_item['num'] = $params_num - $mch['goods_num'];//1 - 2 = -1
  522. $params_num = $params_num - $mch['goods_num'];
  523. if ($mch['goods_num'] <= 0) {
  524. continue;
  525. }
  526. if (intval($type)) {
  527. $agentFrontCentralizeGoodsExt->pre_sorting_num = $mch['goods_num'];
  528. if (!$agentFrontCentralizeGoodsExt->save()) {
  529. throw new \Exception(implode(';', $agentFrontCentralizeGoodsExt->firstErrors));
  530. }
  531. } else {
  532. $order['id'] = $agentFrontCentralizeGoodsExt->cloud_order_id;//用不上 是0
  533. $md = Md::findOne($mch['md_id']);
  534. $lat = $md->latitude;
  535. $lng = $md->longitude;
  536. //获取门店绑定的司机 用于区分货应该分配到那条线路或者说分给哪个司机
  537. $getStoreDriver = $self->getLocDriver($agent_id, $mch['md_id']);
  538. $attr_info = json_decode($agentFrontCentralizeGoods->attr_info, true);
  539. $attr_list = $attr_info['attr_list'];
  540. $goods = [
  541. 'goods_attr' => json_encode($attr_list, JSON_UNESCAPED_UNICODE),
  542. 'goods_name' => $agentFrontCentralizeGoods->goods_name,
  543. 'pic_url' => $agentFrontCentralizeGoods->pic_url,
  544. 'goods_num' => $mch['goods_num'],
  545. 'centralize_goods_id' => $agentFrontCentralizeGoods->id,
  546. 'centralize_goods_ext_id' => $agentFrontCentralizeGoodsExt->id,
  547. 'goods_no' => $agentFrontCentralizeGoods->goods_no,
  548. 'sort_key' => $agentFrontCentralizeGoodsExt->sort_key ?: 0,
  549. ];
  550. if($getStoreDriver['code'] != 0){
  551. // $addDriverLine = $self->addDriverLineOrder($agent_id, $order, $goods, $mch, null, $lat, $lng, '没有匹配的线路');
  552. return $getStoreDriver;
  553. } else {
  554. //完成商品线路分拣
  555. $addDriverLine = $self->addDriverLineOrder($agent_id, $order, $goods, $mch, $getStoreDriver['driver'], $lat, $lng);
  556. }
  557. if($addDriverLine['code'] != 0){
  558. throw new \Exception($addDriverLine['msg']);
  559. }
  560. $agentFrontCentralizeGoodsExt->sorting_num += $mch['goods_num'];
  561. if ($agentFrontCentralizeGoodsExt->sorting_num == $agentFrontCentralizeGoodsExt->goods_num) {
  562. $agentFrontCentralizeGoodsExt->status = AgentFrontCentralizeGoodsExt::STATUS_WAIT_CAR_LOADING;
  563. }
  564. if (!$agentFrontCentralizeGoodsExt->save()) {
  565. throw new \Exception(implode(';', $agentFrontCentralizeGoodsExt->firstErrors));
  566. }
  567. $agentFrontCentralizeGoods->sorting_num += $mch['goods_num'];
  568. if ( $agentFrontCentralizeGoods->sorting_num == $agentFrontCentralizeGoods->goods_num) {
  569. $agentFrontCentralizeGoods->status = AgentFrontCentralizeGoods::STATUS_NO_CAR_LOADING;
  570. $open = true;
  571. }
  572. if (!$agentFrontCentralizeGoods->save()) {
  573. throw new \Exception(implode(';', $agentFrontCentralizeGoods->firstErrors));
  574. }
  575. }
  576. }
  577. }
  578. $t->commit();
  579. return [
  580. 'code' => 0,
  581. 'msg' => 'ok',
  582. 'data' => [
  583. 'status' => $open
  584. ]
  585. ];
  586. } catch (\Exception $e) {
  587. $t->rollBack();
  588. \Yii::error([__METHOD__, $e]);
  589. return [
  590. 'code' => 1,
  591. 'msg' => $e->getMessage() . $e->getLine()
  592. ];
  593. }
  594. }
  595. public function getLine($cloud_store_id, $driver, $md_id = 0) {
  596. $lines = DriverLine::find()->where(['driver_id' => $driver->id, 'status' => DriverLine::STATUS_NOT_CAR_LOADING, 'is_delete' => 0])->orderBy('id asc')->all();
  597. $current_line = [];
  598. foreach($lines as $line){
  599. $lo = DriverLineOrder::findOne(['line_id' => $line->id, 'cloud_store_id' => $cloud_store_id, 'md_id' => $md_id]);
  600. if($lo){
  601. return $line;
  602. }
  603. $current_line = $line;
  604. }
  605. if($current_line){
  606. return $current_line;
  607. }
  608. $line = new DriverLine();
  609. $line->driver_id = $driver->id;
  610. $line->line_no = 'DL' . date('YmdHis') . ($driver->id + 100000000) . rand(1000, 9999);
  611. $line->status = DriverLine::STATUS_NOT_CAR_LOADING;
  612. $save = $line->save();
  613. if(!$save){
  614. throw new \Exception(array_shift($line->getFirstErrors()));
  615. }
  616. return $line;
  617. }
  618. //生成线路配货单
  619. public function addDriverLineOrder($agent_id, $order, $goods, $mch, $driver, $lat, $lng, $errmsg = '') {
  620. try {
  621. $line = null;
  622. if($driver){
  623. // $line = DriverLine::findOne(['driver_id' => $driver->id, 'status' => 0, 'is_delete' => 0]);
  624. $line = $this->getLine($mch['store_id'], $driver, $mch['md_id'] ?? 0);
  625. }
  626. // $address = $store->address;
  627. // $tel = $mch['tel'];
  628. // $name = $mch['name'];
  629. $md = Md::findOne($mch['md_id']);
  630. if (empty($md)) {
  631. throw new \Exception('门店信息异常');
  632. }
  633. $lat = $md->latitude ?: $lat;
  634. $lng = $md->longitude ?: $lng;
  635. $address = $md->address;
  636. $tel = $md->mobile;
  637. $name = $md->name;
  638. $attr_name = [];
  639. $attrs = json_decode($goods['goods_attr'], true);
  640. foreach ($attrs as $iattr) {
  641. $attr_name[] = $iattr['attr_name'];
  642. }
  643. $attr_id = array_column($attrs, 'attr_id');
  644. sort($attr_id);
  645. $lineOrder = new DriverLineOrder();
  646. $lineOrder->agent_id = $agent_id;
  647. if($line){
  648. $lineOrder->line_id = $line->id;
  649. $lineOrder->line_no = $line->line_no;
  650. }
  651. $lineOrder->order_id = $order['id'];
  652. $lineOrder->cloud_store_id = $mch['store_id'];
  653. $lineOrder->store_name = $name;
  654. $lineOrder->store_tel = $tel;
  655. $lineOrder->store_addr = $address;
  656. $lineOrder->lat = $lat;
  657. $lineOrder->lng = $lng;
  658. $lineOrder->goods_no = $goods['goods_no'];;
  659. $lineOrder->goods_name = $goods['goods_name'];
  660. $lineOrder->goods_logo = $goods['pic_url'];
  661. $lineOrder->goods_attr_name = implode(',', $attr_name);
  662. $lineOrder->goods_num = $goods['goods_num'];;
  663. $lineOrder->md_id = $mch['md_id'] ?? 0;
  664. if($errmsg){
  665. $lineOrder->errmsg = $errmsg;
  666. }
  667. $lineOrder->centralize_goods_id = $goods['centralize_goods_id'];
  668. $lineOrder->centralize_goods_ext_id = $goods['centralize_goods_ext_id'];
  669. $lineOrder->sortkey = $goods['sort_key'];
  670. $save = $lineOrder->save();
  671. if(!$save){
  672. throw new \Exception(implode(';', $lineOrder->firstErrors));
  673. }
  674. $this->lineOrderSort($line->id);
  675. return [
  676. 'code' => 0,
  677. 'msg' => 'ok'
  678. ];
  679. } catch (\Exception $e) {
  680. \Yii::error([__METHOD__, $e]);
  681. return [
  682. 'code' => 1,
  683. 'msg' => $e->getMessage() . $e->getLine()
  684. ];
  685. }
  686. }
  687. //获取商城列表(附带字段)
  688. public function getStoreListField($field = 'coordinate')
  689. {
  690. try {
  691. $query = Store::find()->where(['s.is_delete' => 0])->alias('s');
  692. $admin = get_admin();
  693. $admin_id = $admin->id;
  694. if ($admin->username == 'admin') {
  695. $admin_id = null;
  696. }if ($admin_id) {
  697. $ids = Salesman::find()->where(['admin_id' => $admin_id, 'is_delete' => 0])->select('id')->asArray()->all();
  698. $admin_model = Admin::findOne($admin_id);
  699. $area_level = $admin_model->area_level;
  700. if($area_level == 1){
  701. $query->andWhere([
  702. 'or',
  703. ['s.province_id' => $admin_model->province_id, 's.city_id' => $admin_model->city_id, 's.district_id' => $admin_model->district_id],
  704. ['s.admin_id' => $admin_id],
  705. ['in', 's.salesman_id', array_column($ids, 'id')]
  706. ]);
  707. } elseif ($area_level == 2){
  708. $query->andWhere([
  709. 'or',
  710. ['s.province_id' => $admin_model->province_id, 's.city_id' => $admin_model->city_id],
  711. ['s.admin_id' => $admin_id],
  712. ['in', 's.salesman_id', array_column($ids, 'id')]
  713. ]);
  714. } elseif ($area_level == 3){
  715. $query->andWhere([
  716. 'or',
  717. ['s.province_id' => $admin_model->province_id],
  718. ['s.admin_id' => $admin_id],
  719. ['in', 's.salesman_id', array_column($ids, 'id')]
  720. ]);
  721. } else {
  722. $query->andWhere([
  723. 'or',
  724. ['s.admin_id' => $admin_id],
  725. ['in', 's.salesman_id', array_column($ids, 'id')]
  726. ]);
  727. }
  728. }
  729. $store = $query->select('s.id, s.logo, s.name')->addSelect($field)->all();
  730. return [
  731. 'code' => 0,
  732. 'msg' => "获取成功",
  733. 'data' => $store
  734. ];
  735. } catch (\Exception $e) {
  736. \Yii::error([__METHOD__, $e]);
  737. return [
  738. 'code' => 1,
  739. 'msg' => $e->getMessage()
  740. ];
  741. }
  742. }
  743. //先不用了 用下面的方法
  744. public function lineOrderSort_old($line_id) {
  745. try{
  746. $line_order = DriverLineOrder::find()->where(['line_id' => $line_id, 'is_delete' => 0])->groupBy('md_id')->all();
  747. $addr = [];
  748. foreach($line_order as $lorder){
  749. $lan = [$lorder['lat'], $lorder['lng']];
  750. sort($lan);
  751. $addr[] = implode(',', $lan);
  752. }
  753. $driverLine = DriverLine::findOne($line_id);
  754. $driver = Driver::findOne($driverLine['driver_id']);
  755. $admin = \app\models\Admin::findOne($driver['admin_id']);
  756. $from = [$admin['lat'], $admin['lng']];
  757. sort($from);
  758. $from = implode(',', $from);
  759. $to = implode(';', $addr);
  760. $sort = $this->sortDistanceLoc($from, $to);
  761. $sortKey = 1;
  762. foreach($sort as $is => $iv){
  763. $key = substr($is, 1);
  764. // var_dump($key);
  765. $lorder = $line_order[$key];
  766. DriverLineOrder::updateAll(['sortkey' => $sortKey], ['line_id' => $lorder['line_id'], 'md_id' => $lorder['md_id']]);
  767. $sortKey++;
  768. }
  769. return [
  770. 'code' => 0,
  771. 'msg' => "获取成功"
  772. ];
  773. } catch (\Exception $e) {
  774. \Yii::error([__METHOD__, $e]);
  775. return [
  776. 'code' => 1,
  777. 'msg' => $e->getMessage()
  778. ];
  779. }
  780. }
  781. public function lineOrderSort($line_id) {
  782. //查询当前线路下所有的订单
  783. $line_order = DriverLineOrder::find()->where(['line_id' => $line_id, 'is_delete' => 0])->groupBy('md_id')->asArray()->all();
  784. $line_md_id = [];
  785. $max_sort_key = 0;
  786. foreach ($line_order as $item) {
  787. //获取单个门店中所有下单商品的资料 获取时候存在团商品就修改编号 如果不存在就进行排序操作
  788. $centralize_goods_ext_id = DriverLineOrder::find()->where(['line_id' => $line_id, 'md_id' => $item['md_id']])
  789. ->groupBy('md_id')->select('GROUP_CONCAT(centralize_goods_ext_id) as centralize_goods_ext_id')->scalar();
  790. $centralize_goods_ext_id = explode(',', $centralize_goods_ext_id);
  791. $sort_key = AgentFrontCentralizeGoodsExt::find()->where(['id' => $centralize_goods_ext_id])->max('sort_key') ?: 0;
  792. if ($max_sort_key < $sort_key) {
  793. $max_sort_key = $sort_key;
  794. }
  795. if ($sort_key > 0) {//团货
  796. DriverLineOrder::updateAll(['sortkey' => $sort_key], ['line_id' => $line_id, 'md_id' => $item['md_id']]);
  797. } else {//线货
  798. $line_md_id[] = $item['md_id'];
  799. }
  800. }
  801. //将线商品订单排序 格式 最大排序序号-当前序号
  802. foreach ($line_md_id as $line_md_index => $line_md_item) {
  803. $sort_key = $max_sort_key . '-' . ($line_md_index + 1);
  804. DriverLineOrder::updateAll(['sortkey' => $sort_key], ['line_id' => $line_id, 'md_id' => $line_md_item]);
  805. }
  806. }
  807. /**
  808. * 修改配送顺序
  809. */
  810. public function setLineOrderSort() {
  811. $t = \Yii::$app->db->beginTransaction();
  812. try {
  813. $id = $this->id;
  814. $sortKey = $this->sortkey;
  815. if ($sortKey === null) {
  816. throw new \Exception('缺少配送序号');
  817. }
  818. $line_order = DriverLineOrder::findOne($id);
  819. if (!$line_order) {
  820. throw new \Exception('订单不存在');
  821. }
  822. if (intval($line_order->sortkey) === intval($sortKey)) {
  823. return [
  824. 'code' => 0,
  825. 'msg' => '修改成功'
  826. ];
  827. }
  828. $driverLine = DriverLine::findOne($line_order->line_id);
  829. if ($driverLine) {
  830. if (!in_array($driverLine->status, [DriverLine::STATUS_WAIT, DriverLine::STATUS_NOT_CAR_LOADING]) ) {
  831. throw new \Exception('当前状态不可修改配送序号');
  832. }
  833. }
  834. //增加操作日志(获取配置)
  835. $admin = get_admin();
  836. $staff_id = 0;
  837. $front_agent_admin_id = $admin->id;
  838. if ($admin->type === Admin::ADMIN_TYPE_FRONT_AGENT_STAFF) {
  839. $staff_id = $admin->type_id;
  840. $agentFrontStaff = AgentFrontStaff::findOne($staff_id);
  841. $front_agent_admin_id = $agentFrontStaff->front_agent_admin_id;
  842. }
  843. $line_order_key = DriverLineOrder::findOne(['line_id' => $line_order->line_id, 'sortkey' => $sortKey]);
  844. if ($line_order_key) {
  845. DriverLineOrder::updateAll(['sortkey' => $line_order->sortkey], [
  846. 'line_id' => $line_order_key->line_id,
  847. 'md_id' => $line_order_key->md_id
  848. ]);
  849. $md = Md::findOne($line_order_key->md_id);
  850. //增加操作日志(增加记录)
  851. AgentFrontStaffOperateLog::addOperateLog(
  852. AgentFrontStaffOperateLog::OPERATE_TYPE_SET_ROUTE,
  853. $staff_id,
  854. $front_agent_admin_id,
  855. $line_order->line_id,
  856. "修改配送顺序:投篮单号:" . $line_order_key->line_no . ';配送门店:' . $md->name . '(' . $line_order_key->md_id . ')' . ';顺序:' . $line_order->sortkey,
  857. );
  858. }
  859. DriverLineOrder::updateAll(['sortkey' => $sortKey], ['line_id' => $line_order->line_id, 'md_id' => $line_order->md_id]);
  860. $md = Md::findOne($line_order->md_id);
  861. //增加操作日志(增加记录)
  862. AgentFrontStaffOperateLog::addOperateLog(
  863. AgentFrontStaffOperateLog::OPERATE_TYPE_SET_ROUTE,
  864. $staff_id,
  865. $front_agent_admin_id,
  866. $line_order->line_id,
  867. "修改配送顺序:投篮单号:" . $line_order_key->line_no . ';配送门店:' . $md->name . '(' . $line_order->md_id . ')' . ';顺序:' . $sortKey,
  868. );
  869. $t->commit();
  870. return [
  871. 'code' => 0,
  872. 'msg' => '操作成功'
  873. ];
  874. } catch (\Exception $e) {
  875. $t->rollBack();
  876. return [
  877. 'code' => 1,
  878. 'msg' => $e->getMessage()
  879. ];
  880. }
  881. }
  882. /**
  883. * 查询司机绑定门店列表
  884. */
  885. public function bindMdList() {
  886. try {
  887. $driver_id = $this->driver_id;
  888. $tel = $this->tel;
  889. $name = $this->name;
  890. $open_status = $this->open_status;
  891. $query = DriverMdBind::find()->alias('dm')->leftJoin(['m' => Md::tableName()], 'dm.md_id=m.id')
  892. ->where(['dm.is_delete' => 0, 'm.is_delete' => 0, 'driver_id' => $driver_id]);
  893. if (!empty(trim($name))) {
  894. $query->andWhere(['like', 'm.name', $name]);
  895. }
  896. if (!empty(trim($tel))) {
  897. $query->andWhere(['like', 'm.mobile', $tel]);
  898. }
  899. if ($open_status !== null && in_array($open_status, [0, 1])) {
  900. // 不知道数据库能不能直接对时间进行比较 按照网上教程来直接进行比较 测试没啥问题
  901. $time = date('H:i');
  902. $query->andWhere(['m.open_status' => $open_status]);
  903. if ($open_status) {
  904. $query->andWhere(['AND', ['<', 'start_time', $time], ['>', 'end_time', $time]]);
  905. } else {
  906. $query->andWhere(['OR', ['>', 'start_time', $time], ['<', 'end_time', $time]]);
  907. }
  908. }
  909. $query->select('dm.id, m.id as md_id, m.name, m.mobile, m.address, m.cover_url,
  910. m.province, m.city, m.district, dm.created_at, m.open_status, m.start_time,
  911. m.end_time')->orderBy('dm.created_at DESC');
  912. $list = pagination_make($query);
  913. foreach ($list['list'] as $index => &$item) {
  914. $item['open_status'] = intval($item['open_status']);
  915. //是否打烊 根据时间判断一下
  916. if (!empty(trim($item['start_time'])) && !empty(trim($item['end_time']))) {
  917. $start_time = date('Y-m-d ' . $item['start_time']);
  918. $end_time = date('Y-m-d ' . $item['end_time']);
  919. if (time() < strtotime($start_time) || time() > strtotime($end_time)) {
  920. $item['open_status'] = 0;
  921. }
  922. }
  923. $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
  924. $district = District::find()->where(['id' => [$item['province'], $item['city'], $item['district']]])
  925. ->select('name')->column();
  926. $item['address'] = implode(' ', $district) . $item['address'];
  927. }
  928. $md_list = AgentFrontBind::getAgentFrontBindMdList(get_admin()->id);
  929. $md_id_list = array_column($md_list, 'id');
  930. $driverMdBind = DriverMdBind::find()->where(['is_delete' => 0, 'md_id' => $md_id_list])
  931. ->select('md_id')->column();
  932. $md_id_list = array_diff($md_id_list, $driverMdBind);
  933. $list['md_list'] = Md::find()->where(['id' => $md_id_list])->select('id, name')->asArray()->all();
  934. return [
  935. 'code' => 0,
  936. 'msg' => 'ok',
  937. 'data' => $list
  938. ];
  939. } catch (\Exception $e) {
  940. return [
  941. 'code' => 1,
  942. 'msg' => $e->getMessage()
  943. ];
  944. }
  945. }
  946. /**
  947. * 仓库司机绑定门店
  948. */
  949. public function driverBindMd() {
  950. try {
  951. $driver_id = $this->driver_id;
  952. $md_id = $this->md_id;
  953. $form = new DriverMdBind();
  954. $form->md_id = $md_id;
  955. $form->driver_id = $driver_id;
  956. if (!$form->save()) {
  957. throw new \Exception(implode(';', array_values($form->firstErrors)));
  958. }
  959. return [
  960. 'code' => 0,
  961. 'msg' => '绑定成功'
  962. ];
  963. } catch (\Exception $e) {
  964. return [
  965. 'code' => 1,
  966. 'msg' => $e->getMessage()
  967. ];
  968. }
  969. }
  970. /**
  971. * 删除司机绑定门店
  972. */
  973. public function deleteDriverBind() {
  974. try {
  975. $ids = explode(',', $this->ids);
  976. foreach ($ids as $id) {
  977. $model = DriverMdBind::findOne($id);
  978. if (!$model) {
  979. throw new \Exception('记录不存在');
  980. }
  981. if (intval($model->is_delete)) {
  982. throw new \Exception('记录已删除');
  983. }
  984. $model->is_delete = 1;
  985. if (!$model->save()) {
  986. throw new \Exception(implode(';', array_values($model->firstErrors)));
  987. }
  988. }
  989. return [
  990. 'code' => 0,
  991. 'msg' => '操作成功'
  992. ];
  993. } catch (\Exception $e) {
  994. return [
  995. 'code' => 1,
  996. 'msg' => $e->getMessage()
  997. ];
  998. }
  999. }
  1000. public function geocoder($address = ''){
  1001. $tencent_map_key = Option::get('tencent_map_key', 0, 'saas', '')['value'];
  1002. $url = 'https://apis.map.qq.com/ws/geocoder/v1/?';
  1003. $params = [
  1004. 'key' => $tencent_map_key,
  1005. 'address' => $address,
  1006. ];
  1007. $url .= http_build_query($params);
  1008. $json = file_get_contents($url);
  1009. $res = json_decode($json, true);
  1010. if($res['status'] == 0 && $res['result']['location']){
  1011. return $res['result']['location'];
  1012. }
  1013. return ['lng' => '', 'lat' => ''];
  1014. }
  1015. public function distanceMatrix($from = '39.071510,117.190091', $to = '39.071510,117.190091;40.007632,116.389160'){
  1016. $url = 'https://apis.map.qq.com/ws/distance/v1/matrix?';
  1017. $tencent_map_key = Option::get('tencent_map_key', 0, 'saas', '')['value'];
  1018. $params = [
  1019. 'key' => $tencent_map_key,
  1020. 'from' => $from,
  1021. 'to' => $to,
  1022. 'mode' => 'driving',
  1023. ];
  1024. $url .= http_build_query($params);
  1025. // var_dump($url);
  1026. $json = file_get_contents($url);
  1027. // var_dump($json);
  1028. // $json = '{"status":0,"message":"query ok","request_id":"3940191711926976785","result":{"rows":[{"elements":[{"distance":7040,"duration":1146},{"distance":12416,"duration":1501}]},{"elements":[{"distance":6132,"duration":847},{"distance":9476,"duration":1049}]}]}}';
  1029. $res = json_decode($json, true);
  1030. if($res['status'] == 0 && $res['result']['rows'][0]['elements']){
  1031. return $res['result']['rows'][0]['elements'];
  1032. }
  1033. return null;
  1034. }
  1035. //腾讯接口距离排序
  1036. public function sortDistance($from, $to) {
  1037. $matrix = $this->distanceMatrix($from, $to);
  1038. // var_dump($matrix);die;
  1039. if(!$matrix){
  1040. throw new \Exception('距离排序错误');
  1041. }
  1042. $res = [];
  1043. foreach ($matrix as $i => $item) {
  1044. $res['a'.$i] = $item['duration'];
  1045. }
  1046. // var_dump($res);
  1047. asort($res);
  1048. // var_dump($res);
  1049. return $res;
  1050. }
  1051. //本地距离排序
  1052. public function sortDistanceLoc($from, $to) {
  1053. $to = explode(';', $to);
  1054. $res = [];
  1055. foreach($to as $i => &$item){
  1056. $item = explode(',', $item);
  1057. $item[2] = $i;
  1058. }
  1059. $from = explode(',', $from);
  1060. $point1 = $from;
  1061. while(count($to)){
  1062. $dist1 = 99999;
  1063. $t = 0;
  1064. foreach ($to as $i => $point2) {
  1065. $dist = $this->distance($point1, $point2);
  1066. if($dist < $dist1){
  1067. $dist1 = $dist;
  1068. $t = $i;
  1069. }
  1070. }
  1071. $point1 = $to[$t];
  1072. $res[] = $to[$t];
  1073. unset($to[$t]);
  1074. }
  1075. $res2 = [];
  1076. foreach($res as $item){
  1077. $res2['a' . $item[2]] = 1;
  1078. }
  1079. return $res2;
  1080. }
  1081. public function distance($point1, $point2) {
  1082. $x = abs($point2[0] - $point1[0]);
  1083. $y = abs($point2[1] - $point1[1]);
  1084. return $x * $x + $y * $y;
  1085. }
  1086. }