| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242 |
- <?php
- /**
- * 重庆赤晓店信息科技有限公司
- * https://www.chixiaodian.com
- * Copyright (c) 2023 赤店商城 All rights reserved.
- */
- namespace app\modules\admin\models;
- use app\models\Admin;
- use app\models\AgentFrontBind;
- use app\models\AgentFrontCentralizeGoods;
- use app\models\AgentFrontCentralizeGoodsCancelLog;
- use app\models\AgentFrontCentralizeGoodsExt;
- use app\models\AgentFrontStaff;
- use app\models\AgentFrontStaffOperateLog;
- use app\models\District;
- use app\models\DriverMdBind;
- use app\models\Md;
- use app\models\Option;
- use app\models\StoreCloud;
- use yii\base\Model;
- use app\models\Store;
- use app\models\SaasUser;
- use app\models\Driver;
- use app\models\DriverLine;
- use app\models\DriverLineOrder;
- class DriverForm extends Model
- {
- public $page = 1;
- public $limit = 10;
- public $id;
- public $line_name;
- public $name;
- public $tel;
- public $car_no;
- public $admin_id;
- public $status;
- public $md_id;
- public $driver_id;
- public $open_status;
- public $ids;
- public $goods_num;
- public $car_loading_pic;
- public $goods_no;
- public $goods_name;
- public $is_car_loading;
- public $sortkey;
- public $params;
- public $type;
- public function rules()
- {
- return [
- [['id', 'md_id', 'driver_id', 'open_status', 'goods_num', 'is_car_loading', 'sortkey', 'type'], 'integer'],
- [['tel', 'name', 'ids', 'goods_no', 'goods_name', 'car_loading_pic', 'params'], 'string']
- ];
- }
- public function driverList() {
- $query = Driver::find()->where(['admin_id' => $this->admin_id, 'is_delete' => 0]);
- if($this->name){
- $query->andWhere(['like', 'name', $this->name]);
- }
- if($this->car_no){
- $query->andWhere(['car_no' => $this->car_no]);
- }
- if($this->tel){
- $saasUser = SaasUser::findOne(['mobile' => $this->tel, 'is_delete' => 0]);
- if($saasUser){
- $query->andWhere(['saas_user_id' => $saasUser->id]);
- }
- }
- $query->orderBy('id desc');
- $res = pagination_make($query);
- foreach ($res['list'] as &$item) {
- $saas_user_id = $item['saas_user_id'] ?? 0;
- $saas_user = SaasUser::findOne($saas_user_id);
- $item['saas_user'] = $saas_user ?? [
- 'name' => ''
- ];
- $item['md_count'] = DriverMdBind::find()->where(['driver_id' => $item['id'], 'is_delete' => 0])->select('md_id')->count();
- }
- $res['tencent_map_key'] = Option::get('tencent_map_key', 0, 'saas', '')['value'];
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $res,
- ];
- }
- public function driverSave($id, $admin_id, $saas_user_id, $name, $car_no, $tel, $line_name, $area = [], $status = 1) {
- try{
- if(empty($admin_id)){
- throw new \Exception('代理用户不能为空');
- }
- // if(!is_array($area) || empty($area)){
- // throw new \Exception('区域格式不正确');
- // }
- if(empty($saas_user_id)){
- throw new \Exception('绑定用户不能为空');
- }
- $model = $id ? Driver::findOne($id) : new Driver();
- $model->admin_id = $admin_id;
- $model->saas_user_id = $saas_user_id;
- $model->name = $name;
- $model->car_no = $car_no;
- $model->tel = $tel;
- $model->line_name = $line_name;
- $model->area = json_encode($area);
- $model->status = $status;
- $save = $model->save();
- if(!$save){
- throw new \Exception('操作失败,' . array_shift($model->getFirstErrors()));
- }
- return [
- 'code' => 0,
- 'msg' => '操作成功',
- ];
- }catch(\Exception $e){
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage(),
- ];
- }
- }
- public function driverStatus ($ids, $status)
- {
- try {
- if ($ids) {
- is_string($ids) && $ids = explode(',', $ids);
- if (in_array($status, [0, 1])) {
- Driver::updateAll(['status' => $status], ['and', ['in', 'id', $ids], ['is_delete' => 0]]);
- }
- if ((int)$status === 2) {
- Driver::updateAll(['is_delete' => 1], ['and', ['in', 'id', $ids], ['is_delete' => 0]]);
- }
- }
- return [
- 'code' => 0,
- 'msg' => '操作成功!'
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- public function driverLineList() {
- $query = DriverLine::find()->alias('dl')->where(['dl.is_delete' => 0]);
- $query->leftJoin(['d' => Driver::tableName()], 'd.id=dl.driver_id');
- $query->andWhere(['d.admin_id' => $this->admin_id]);
- if($this->name){
- $query->andWhere(['like', 'd.name', $this->name]);
- }
- if($this->line_name){
- $query->andWhere(['like', 'd.line_name', $this->line_name]);
- }
- if($this->car_no){
- $query->andWhere(['d.car_no' => $this->car_no]);
- }
- if($this->is_car_loading !== null && in_array($this->is_car_loading, [0, 1])) {
- if (!$this->is_car_loading) {
- $query->andWhere(['dl.status' => DriverLine::STATUS_NOT_CAR_LOADING]);
- } else {
- $query->andWhere(['dl.status' => [
- DriverLine::STATUS_WAIT,
- DriverLine::STATUS_DOING,
- DriverLine::STATUS_FINISH
- ]]);
- }
- }
- if($this->status !== null && in_array($this->status, [
- DriverLine::STATUS_NOT_CAR_LOADING,
- DriverLine::STATUS_WAIT,
- DriverLine::STATUS_DOING,
- DriverLine::STATUS_FINISH
- ])){
- $query->andWhere(['dl.status' => $this->status]);
- }
- if($this->tel){
- $query->andWhere(['LIKE', 'd.tel', $this->tel]);
- }
- $query->select('dl.id, dl.status, dl.finish_time, dl.driver_id')->orderBy('dl.id desc');
- $res = pagination_make($query);
- foreach ($res['list'] as &$item) {
- $driver = Driver::findOne($item['driver_id']);
- $lineOrderCount = DriverLineOrder::find()->where(['line_id' => $item['id'], 'is_delete' => 0])->groupBy('md_id')->count() ?: 0;
- $saas_user_id = $driver['saas_user_id'] ?? 0;
- // $saas_user = SaasUser::findOne($saas_user_id);
- // $item['saas_user'] = $saas_user;
- $item['driver'] = [
- 'line_name' => $driver->line_name,
- 'name' => $driver->name,
- 'car_no' => $driver->car_no,
- 'tel' => $driver->tel
- ];
- $item['lineOrderCount'] = $lineOrderCount;
- $item['orderGoodsCount'] = DriverLineOrder::find()->where(['line_id' => $item['id'], 'is_delete' => 0])->count() ?: 0;
- }
- return [
- 'code' => 0,
- 'msg' => 'success',
- 'data' => $res,
- ];
- }
- public function driverLineInfo() {
- $driver_line = DriverLine::findOne($this->id);
- $driver = Driver::findOne($driver_line->driver_id);
- $driver_line_order = [];
- $driver_line_order1 = DriverLineOrder::find()->where(['line_id' => $driver_line->id, 'is_delete' => 0])->orderBy('sortkey, goods_name')->asArray()->all();
- foreach ($driver_line_order1 as $item) {
- if(isset($driver_line_order[$item['md_id']])){
- $has = 0;
- foreach($driver_line_order[$item['md_id']]['goods'] as &$order){
- if($order['goods_name'] == $item['goods_name'] && $order['goods_attr_name'] == $item['goods_attr_name']){
- $has = 1;
- $order['goods_num'] += $item['goods_num'];
- }
- }
- if(!$has){
- $driver_line_order[$item['md_id']]['goods'][] = $item;
- }
- }else{
- $driver_line_order[$item['md_id']] = $item;
- $driver_line_order[$item['md_id']]['goods'] = [$item];
- }
- $store_cloud = StoreCloud::findOne(['cloud_store_id' => $item['cloud_store_id'], 'is_delete' => 0]);
- $store = Store::findOne($store_cloud->store_id);
- $store_name = $store->name;
- if ($item['md_id'] > 0) {
- $mdInfo = Md::findOne($item['md_id']);
- $store_name = $mdInfo->name ?? $store_name;
- }
- $driver_line_order[$item['md_id']]['store_name'] = $store_name;
- }
- $driver_line_order = array_values($driver_line_order);
- $lineOrderCount = DriverLineOrder::find()->where(['line_id' => $driver_line->id, 'is_delete' => 0])->groupBy('cloud_store_id')->count();
- return [
- 'code' => 0,
- 'driver_line' => $driver_line,
- 'driver' => $driver,
- 'driver_line_order' => $driver_line_order,
- 'lineOrderCount' => $lineOrderCount,
- ];
- }
- //点击装车
- public function driverLineStart()
- {
- try {
- $driver_line = DriverLine::findOne($this->id);
- if (!$driver_line) {
- throw new \Exception('订单未找到');
- }
- if (intval($driver_line->status) !== DriverLine::STATUS_NOT_CAR_LOADING) {
- throw new \Exception('已经装车 请勿重复操作');
- }
- if (empty(trim($this->car_loading_pic))) {
- throw new \Exception('缺失装车图片');
- }
- $driver_line->status = DriverLine::STATUS_WAIT;
- $driver_line->car_loading_time = time();
- $driver_line->car_loading_pic = $this->car_loading_pic;
- if (!$driver_line->save()) {
- throw new \Exception(implode(';', array_values($driver_line->firstErrors)));
- }
- return [
- 'code' => 0,
- 'msg' => '操作成功',
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage(),
- ];
- }
- }
- //获取装车明细
- public function carLoadingDetail() {
- try {
- $id = $this->id;
- $driver_line = DriverLine::findOne($id);
- if (!$driver_line) {
- throw new \Exception('订单未找到');
- }
- $goods_name = $this->goods_name;
- $goods_no = $this->goods_no;
- $query = DriverLineOrder::find()->alias('dlo')
- ->leftJoin(['g' => AgentFrontCentralizeGoods::tableName()], 'dlo.centralize_goods_id = g.id')
- ->where(['dlo.line_id' => $id, 'dlo.is_delete' => 0, 'g.is_delete' => 0])->groupBy('dlo.centralize_goods_id');
- if (!empty(trim($goods_name))) {
- $query->andWhere(['LIKE', 'dlo.goods_name', trim($goods_name)]);
- }
- if (!empty(trim($goods_no))) {
- $query->andWhere(['LIKE', 'g.goods_no', trim($goods_no)]);
- }
- $query->select('dlo.id, dlo.goods_name, dlo.goods_attr_name, g.goods_no, g.centralize_goods_type,
- dlo.centralize_goods_id, g.pic_url, SUM(dlo.cancel_goods_num) as cancel_num')
- ->orderBy('dlo.id DESC');
- $list = pagination_make($query);
- foreach ($list['list'] as &$item) {
- $centralize_goods_ext_id_arr = DriverLineOrder::find()->where(['centralize_goods_id' => $item['centralize_goods_id'], 'line_id' => $id])
- ->select('centralize_goods_ext_id')->column();
- $agentFrontCentralizeGoodsExtArr = AgentFrontCentralizeGoodsExt::find()->where(['id' => $centralize_goods_ext_id_arr, 'is_delete' => 0])
- ->select('goods_num, sorting_num')->asArray()->all();
- $item['order_num'] = array_sum(array_column($agentFrontCentralizeGoodsExtArr, 'goods_num'));
- $item['sorting_num'] = array_sum(array_column($agentFrontCentralizeGoodsExtArr, 'sorting_num'));
- $item['centralize_goods_type'] = intval($item['centralize_goods_type']);
- }
- return [
- 'code' => 0,
- 'msg' => '',
- 'data' => $list
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage(),
- ];
- }
- }
- // //判断点是否在多边形区域内
- // public function inArea($x,$y,$arr)
- // {
- // //点的数量
- // $count = count($arr);
- // $n = 0; //点与线相交的个数
- // $bool = 0;//外
- // for ($i = 0, $j = $count - 1; $i < $count; $j = $i, $i++) {
- // //两个点一条线 取出两个连接点的定点
- // $px1 = $arr[$i][0];
- // $py1 = $arr[$i][1];
- // $px2 = $arr[$j][0];
- // $py2 = $arr[$j][1];
- // //$x的水平位置画射线
- // if($x>=$px1 || $x>= $px2)
- // {
- // //判断$y 是否在线的区域
- // if(($y>=$py1 && $y<=$py2) || ($y>=$py2 && $y<= $py1)){
- // if (($y == $py1 && $x == $px1) || ($y == $py2 && $x == $px2)) {
- //
- // #如果$x的值和点的坐标相同
- // $bool = 2;//在点上
- // return $bool;
- //
- // }else{
- // $px = $px1+($y-$py1)/($py2-$py1)*($px2-$px1) ;
- // if($px ==$x)
- // {
- // $bool = 3;//在线上
- // }elseif($px< $x){
- // $n++;
- // }
- //
- // }
- // }
- // }
- //
- // }
- // if ($n%2 != 0) {
- // $bool = 1;
- // }
- // return $bool;
- // }
- //获取商城匹配的线路
- public function getLocDriver($agent_id, $md_id) {
- try {
- $driverMdBind = DriverMdBind::findOne(['md_id' => $md_id, 'is_delete' => 0]);
- if (!$driverMdBind) {
- throw new \Exception('分拣订单的来源门店需要绑定线路');
- }
- $driver = Driver::findOne(['admin_id' => $agent_id, 'is_delete' => 0, 'id' => $driverMdBind->driver_id, 'status' => 1]);
- if ($driver) {
- return [
- 'code' => 0,
- 'driver' => $driver,
- ];
- }
- throw new \Exception('司机未绑定当前仓库');
- } catch (\Exception $e) {
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- // public function getOrder($id) {
- //// $form = new SupplierForm();
- //// $form->id = $id;
- //// return $form->agentOrderDistributionList();
- // $form = new PlatformForm();
- // return $form->getSortingOrder($id);
- //
- //
- // }
- //分配异常列表
- public function getOrderToLineErrList($agent_id) {
- $line_orders = DriverLineOrder::find()->where(['agent_id' => $agent_id, 'line_id' => 0])->all();
- return [
- 'code' => 0,
- 'msg' => 'ok',
- 'data' => $line_orders,
- 'count' => count($line_orders),
- ];
- }
- //手动分配路线
- public function setOrderToLine($id, $driver_id, $attr = []) {
- try{
- $line_order = DriverLineOrder::findOne($id);
- foreach($attr as $at => $val){
- $line_order->$at = $val;
- }
- $driver = Driver::findOne($driver_id);
- $line = $this->getLine($line_order['cloud_store_id'], $driver);
- if($line){
- $line_order->line_id = $line->id;
- $line_order->line_no = $line->line_no;
- }
-
- $save = $line_order->save();
- if(!$save){
- throw new \Exception(array_shift($line_order->getFirstErrors()));
- }
- return [
- 'code' => 0,
- 'msg' => 'ok'
- ];
- } catch (\Exception $e) {
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- //拣货
- public function orderToLine() {
- $t = \Yii::$app->db->beginTransaction();
- try {
- $params = $this->params;
- $agent_id = $this->admin_id;
- $type = $this->type; //0分拣 1提交进度不分拣
- // $goods_num = $this->goods_num;
- if (!$params) {
- throw new \Exception('分拣数据错误');
- }
- $params = json_decode($params, true);
- // if ($goods_num <= 0 && count($ids) == 1) {
- // throw new \Exception('分拣数量错误');
- // }
- $open = false;
- $self = new self();
- foreach($params as $params_item){
- // $orders = $self->getOrder($id);
- if ($params_item['num'] <= 0) {
- throw new \Exception('分拣数量错误');
- }
- $params_num = $params_item['num'];
- // $params_num = 0;
- //兼容传多个分拣商品ID 只传递一个数量 比如:[{"id": "72, 73", "num": 2}]
- $ids = explode(',', $params_item['id']);
- foreach ($ids as $id_item) {
- if ($params_item['num'] <= 0) {
- continue;
- }
- $agentFrontCentralizeGoodsExt = AgentFrontCentralizeGoodsExt::find()->where(['id' => $id_item, 'is_delete' => 0])
- ->select('id, centralize_goods_id, cloud_order_id, goods_num, md_id, sorting_num, status')->asArray()->one();
- if (!$agentFrontCentralizeGoodsExt) {
- throw new \Exception('分拣商品信息不存在');
- }
- if (intval($agentFrontCentralizeGoodsExt['status']) !== AgentFrontCentralizeGoodsExt::STATUS_WAIT_SORTING) {
- throw new \Exception('部分订单已分拣完成,请勿重复操作');
- }
- /**
- * ------------
- * 9
- * 3 0
- * 3 0
- * 3 0
- * -----------
- */
- if (count($ids) > 1) {
- $agentFrontCentralizeGoodsExtAll = AgentFrontCentralizeGoodsExt::find()->where(['id' => $ids])
- ->select('goods_num, sorting_num')->asArray()->all();
- $goods_num = array_sum(array_column($agentFrontCentralizeGoodsExtAll, 'goods_num'));//9
- $sorting_num = array_sum(array_column($agentFrontCentralizeGoodsExtAll, 'sorting_num'));//0
- if ($params_item['num'] > ($goods_num - $sorting_num)) {
- throw new \Exception('分拣数量大于剩余待分拣数量');
- }
- if ($params_item['num'] == ($goods_num - $sorting_num)) {// 9 == 9 6 == 9 - 3
- $params_item['num'] = null;
- } else {// 2 >= 2 + 0
- if ($params_item['num'] >= ($agentFrontCentralizeGoodsExt['goods_num'] - $agentFrontCentralizeGoodsExt['sorting_num'])) {//3 >= 2 - 0
- $params_item['num'] = ($agentFrontCentralizeGoodsExt['goods_num'] - $agentFrontCentralizeGoodsExt['sorting_num']);//2-0 = 2
- // $params_num -= $params_item['num'];//3 - 2 = 1
- }
- }
- // if (isset($params_num)) {
- // $params_item['num'] = $params_num;//4 - 2//
- // }
- } else {
- if ($params_item['num'] > ($agentFrontCentralizeGoodsExt['goods_num'] - $agentFrontCentralizeGoodsExt['sorting_num'])) {
- throw new \Exception('分拣数量大于剩余待分拣数量');
- }
- }
- $agentFrontCentralizeGoods = AgentFrontCentralizeGoods::findOne(['id' => $agentFrontCentralizeGoodsExt['centralize_goods_id'], 'is_delete' => 0, 'status' => AgentFrontCentralizeGoods::STATUS_SORTING]);
- if (!$agentFrontCentralizeGoods) {
- throw new \Exception('商品不存在');
- }
- $md = Md::findOne($agentFrontCentralizeGoodsExt['md_id']);
- if (empty($md)) {
- throw new \Exception('门店不存在' . $agentFrontCentralizeGoodsExt['md_id']);
- }
- $agentFrontCentralizeGoodsExt = AgentFrontCentralizeGoodsExt::findOne($agentFrontCentralizeGoodsExt['id']);
- //组装数据
- // $goods_num_arr = array_column($order_list_item['goods_list'], 'num');
- $mch = [
- 'md_id' => $agentFrontCentralizeGoodsExt->md_id,
- 'store_id' => $md->store_id,
- 'tel' => $md->mobile,
- 'name' => $md->name,
- 'goods_num' => $params_item['num'] ?? ($agentFrontCentralizeGoodsExt->goods_num - $agentFrontCentralizeGoodsExt->sorting_num),
- ];
- $params_item['num'] = $params_num - $mch['goods_num'];//1 - 2 = -1
- $params_num = $params_num - $mch['goods_num'];
- if ($mch['goods_num'] <= 0) {
- continue;
- }
- if (intval($type)) {
- $agentFrontCentralizeGoodsExt->pre_sorting_num = $mch['goods_num'];
- if (!$agentFrontCentralizeGoodsExt->save()) {
- throw new \Exception(implode(';', $agentFrontCentralizeGoodsExt->firstErrors));
- }
- } else {
- $order['id'] = $agentFrontCentralizeGoodsExt->cloud_order_id;//用不上 是0
- $md = Md::findOne($mch['md_id']);
- $lat = $md->latitude;
- $lng = $md->longitude;
- //获取门店绑定的司机 用于区分货应该分配到那条线路或者说分给哪个司机
- $getStoreDriver = $self->getLocDriver($agent_id, $mch['md_id']);
- $attr_info = json_decode($agentFrontCentralizeGoods->attr_info, true);
- $attr_list = $attr_info['attr_list'];
- $goods = [
- 'goods_attr' => json_encode($attr_list, JSON_UNESCAPED_UNICODE),
- 'goods_name' => $agentFrontCentralizeGoods->goods_name,
- 'pic_url' => $agentFrontCentralizeGoods->pic_url,
- 'goods_num' => $mch['goods_num'],
- 'centralize_goods_id' => $agentFrontCentralizeGoods->id,
- 'centralize_goods_ext_id' => $agentFrontCentralizeGoodsExt->id,
- 'goods_no' => $agentFrontCentralizeGoods->goods_no,
- 'sort_key' => $agentFrontCentralizeGoodsExt->sort_key ?: 0,
- ];
- if($getStoreDriver['code'] != 0){
- // $addDriverLine = $self->addDriverLineOrder($agent_id, $order, $goods, $mch, null, $lat, $lng, '没有匹配的线路');
- return $getStoreDriver;
- } else {
- //完成商品线路分拣
- $addDriverLine = $self->addDriverLineOrder($agent_id, $order, $goods, $mch, $getStoreDriver['driver'], $lat, $lng);
- }
- if($addDriverLine['code'] != 0){
- throw new \Exception($addDriverLine['msg']);
- }
- $agentFrontCentralizeGoodsExt->sorting_num += $mch['goods_num'];
- if ($agentFrontCentralizeGoodsExt->sorting_num == $agentFrontCentralizeGoodsExt->goods_num) {
- $agentFrontCentralizeGoodsExt->status = AgentFrontCentralizeGoodsExt::STATUS_WAIT_CAR_LOADING;
- }
- if (!$agentFrontCentralizeGoodsExt->save()) {
- throw new \Exception(implode(';', $agentFrontCentralizeGoodsExt->firstErrors));
- }
- $agentFrontCentralizeGoods->sorting_num += $mch['goods_num'];
- if ( $agentFrontCentralizeGoods->sorting_num == $agentFrontCentralizeGoods->goods_num) {
- $agentFrontCentralizeGoods->status = AgentFrontCentralizeGoods::STATUS_NO_CAR_LOADING;
- $open = true;
- }
- if (!$agentFrontCentralizeGoods->save()) {
- throw new \Exception(implode(';', $agentFrontCentralizeGoods->firstErrors));
- }
- }
- }
- }
- $t->commit();
- return [
- 'code' => 0,
- 'msg' => 'ok',
- 'data' => [
- 'status' => $open
- ]
- ];
- } catch (\Exception $e) {
- $t->rollBack();
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage() . $e->getLine()
- ];
- }
- }
- public function getLine($cloud_store_id, $driver, $md_id = 0) {
- $lines = DriverLine::find()->where(['driver_id' => $driver->id, 'status' => DriverLine::STATUS_NOT_CAR_LOADING, 'is_delete' => 0])->orderBy('id asc')->all();
- $current_line = [];
- foreach($lines as $line){
- $lo = DriverLineOrder::findOne(['line_id' => $line->id, 'cloud_store_id' => $cloud_store_id, 'md_id' => $md_id]);
- if($lo){
- return $line;
- }
- $current_line = $line;
- }
- if($current_line){
- return $current_line;
- }
- $line = new DriverLine();
- $line->driver_id = $driver->id;
- $line->line_no = 'DL' . date('YmdHis') . ($driver->id + 100000000) . rand(1000, 9999);
- $line->status = DriverLine::STATUS_NOT_CAR_LOADING;
- $save = $line->save();
- if(!$save){
- throw new \Exception(array_shift($line->getFirstErrors()));
- }
- return $line;
- }
- //生成线路配货单
- public function addDriverLineOrder($agent_id, $order, $goods, $mch, $driver, $lat, $lng, $errmsg = '') {
- try {
- $line = null;
- if($driver){
- // $line = DriverLine::findOne(['driver_id' => $driver->id, 'status' => 0, 'is_delete' => 0]);
- $line = $this->getLine($mch['store_id'], $driver, $mch['md_id'] ?? 0);
- }
- // $address = $store->address;
- // $tel = $mch['tel'];
- // $name = $mch['name'];
- $md = Md::findOne($mch['md_id']);
- if (empty($md)) {
- throw new \Exception('门店信息异常');
- }
- $lat = $md->latitude ?: $lat;
- $lng = $md->longitude ?: $lng;
- $address = $md->address;
- $tel = $md->mobile;
- $name = $md->name;
- $attr_name = [];
- $attrs = json_decode($goods['goods_attr'], true);
- foreach ($attrs as $iattr) {
- $attr_name[] = $iattr['attr_name'];
- }
- $attr_id = array_column($attrs, 'attr_id');
- sort($attr_id);
- $lineOrder = new DriverLineOrder();
- $lineOrder->agent_id = $agent_id;
- if($line){
- $lineOrder->line_id = $line->id;
- $lineOrder->line_no = $line->line_no;
- }
- $lineOrder->order_id = $order['id'];
- $lineOrder->cloud_store_id = $mch['store_id'];
- $lineOrder->store_name = $name;
- $lineOrder->store_tel = $tel;
- $lineOrder->store_addr = $address;
- $lineOrder->lat = $lat;
- $lineOrder->lng = $lng;
- $lineOrder->goods_no = $goods['goods_no'];;
- $lineOrder->goods_name = $goods['goods_name'];
- $lineOrder->goods_logo = $goods['pic_url'];
- $lineOrder->goods_attr_name = implode(',', $attr_name);
- $lineOrder->goods_num = $goods['goods_num'];;
- $lineOrder->md_id = $mch['md_id'] ?? 0;
- if($errmsg){
- $lineOrder->errmsg = $errmsg;
- }
- $lineOrder->centralize_goods_id = $goods['centralize_goods_id'];
- $lineOrder->centralize_goods_ext_id = $goods['centralize_goods_ext_id'];
- $lineOrder->sortkey = $goods['sort_key'];
- $save = $lineOrder->save();
- if(!$save){
- throw new \Exception(implode(';', $lineOrder->firstErrors));
- }
- $this->lineOrderSort($line->id);
- return [
- 'code' => 0,
- 'msg' => 'ok'
- ];
- } catch (\Exception $e) {
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage() . $e->getLine()
- ];
- }
- }
- //获取商城列表(附带字段)
- public function getStoreListField($field = 'coordinate')
- {
- try {
- $query = Store::find()->where(['s.is_delete' => 0])->alias('s');
- $admin = get_admin();
- $admin_id = $admin->id;
- if ($admin->username == 'admin') {
- $admin_id = null;
- }if ($admin_id) {
- $ids = Salesman::find()->where(['admin_id' => $admin_id, 'is_delete' => 0])->select('id')->asArray()->all();
- $admin_model = Admin::findOne($admin_id);
- $area_level = $admin_model->area_level;
- if($area_level == 1){
- $query->andWhere([
- 'or',
- ['s.province_id' => $admin_model->province_id, 's.city_id' => $admin_model->city_id, 's.district_id' => $admin_model->district_id],
- ['s.admin_id' => $admin_id],
- ['in', 's.salesman_id', array_column($ids, 'id')]
- ]);
- } elseif ($area_level == 2){
- $query->andWhere([
- 'or',
- ['s.province_id' => $admin_model->province_id, 's.city_id' => $admin_model->city_id],
- ['s.admin_id' => $admin_id],
- ['in', 's.salesman_id', array_column($ids, 'id')]
- ]);
- } elseif ($area_level == 3){
- $query->andWhere([
- 'or',
- ['s.province_id' => $admin_model->province_id],
- ['s.admin_id' => $admin_id],
- ['in', 's.salesman_id', array_column($ids, 'id')]
- ]);
- } else {
- $query->andWhere([
- 'or',
- ['s.admin_id' => $admin_id],
- ['in', 's.salesman_id', array_column($ids, 'id')]
- ]);
- }
- }
- $store = $query->select('s.id, s.logo, s.name')->addSelect($field)->all();
- return [
- 'code' => 0,
- 'msg' => "获取成功",
- 'data' => $store
- ];
- } catch (\Exception $e) {
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- //先不用了 用下面的方法
- public function lineOrderSort_old($line_id) {
- try{
- $line_order = DriverLineOrder::find()->where(['line_id' => $line_id, 'is_delete' => 0])->groupBy('md_id')->all();
- $addr = [];
- foreach($line_order as $lorder){
- $lan = [$lorder['lat'], $lorder['lng']];
- sort($lan);
- $addr[] = implode(',', $lan);
- }
- $driverLine = DriverLine::findOne($line_id);
- $driver = Driver::findOne($driverLine['driver_id']);
- $admin = \app\models\Admin::findOne($driver['admin_id']);
- $from = [$admin['lat'], $admin['lng']];
- sort($from);
- $from = implode(',', $from);
- $to = implode(';', $addr);
- $sort = $this->sortDistanceLoc($from, $to);
- $sortKey = 1;
- foreach($sort as $is => $iv){
- $key = substr($is, 1);
- // var_dump($key);
- $lorder = $line_order[$key];
- DriverLineOrder::updateAll(['sortkey' => $sortKey], ['line_id' => $lorder['line_id'], 'md_id' => $lorder['md_id']]);
- $sortKey++;
- }
- return [
- 'code' => 0,
- 'msg' => "获取成功"
- ];
- } catch (\Exception $e) {
- \Yii::error([__METHOD__, $e]);
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- public function lineOrderSort($line_id) {
- //查询当前线路下所有的订单
- $line_order = DriverLineOrder::find()->where(['line_id' => $line_id, 'is_delete' => 0])->groupBy('md_id')->asArray()->all();
- $line_md_id = [];
- $max_sort_key = 0;
- foreach ($line_order as $item) {
- //获取单个门店中所有下单商品的资料 获取时候存在团商品就修改编号 如果不存在就进行排序操作
- $centralize_goods_ext_id = DriverLineOrder::find()->where(['line_id' => $line_id, 'md_id' => $item['md_id']])
- ->groupBy('md_id')->select('GROUP_CONCAT(centralize_goods_ext_id) as centralize_goods_ext_id')->scalar();
- $centralize_goods_ext_id = explode(',', $centralize_goods_ext_id);
- $sort_key = AgentFrontCentralizeGoodsExt::find()->where(['id' => $centralize_goods_ext_id])->max('sort_key') ?: 0;
- if ($max_sort_key < $sort_key) {
- $max_sort_key = $sort_key;
- }
- if ($sort_key > 0) {//团货
- DriverLineOrder::updateAll(['sortkey' => $sort_key], ['line_id' => $line_id, 'md_id' => $item['md_id']]);
- } else {//线货
- $line_md_id[] = $item['md_id'];
- }
- }
- //将线商品订单排序 格式 最大排序序号-当前序号
- foreach ($line_md_id as $line_md_index => $line_md_item) {
- $sort_key = $max_sort_key . '-' . ($line_md_index + 1);
- DriverLineOrder::updateAll(['sortkey' => $sort_key], ['line_id' => $line_id, 'md_id' => $line_md_item]);
- }
- }
- /**
- * 修改配送顺序
- */
- public function setLineOrderSort() {
- $t = \Yii::$app->db->beginTransaction();
- try {
- $id = $this->id;
- $sortKey = $this->sortkey;
- if ($sortKey === null) {
- throw new \Exception('缺少配送序号');
- }
- $line_order = DriverLineOrder::findOne($id);
- if (!$line_order) {
- throw new \Exception('订单不存在');
- }
- if (intval($line_order->sortkey) === intval($sortKey)) {
- return [
- 'code' => 0,
- 'msg' => '修改成功'
- ];
- }
- $driverLine = DriverLine::findOne($line_order->line_id);
- if ($driverLine) {
- if (!in_array($driverLine->status, [DriverLine::STATUS_WAIT, DriverLine::STATUS_NOT_CAR_LOADING]) ) {
- throw new \Exception('当前状态不可修改配送序号');
- }
- }
- //增加操作日志(获取配置)
- $admin = get_admin();
- $staff_id = 0;
- $front_agent_admin_id = $admin->id;
- if ($admin->type === Admin::ADMIN_TYPE_FRONT_AGENT_STAFF) {
- $staff_id = $admin->type_id;
- $agentFrontStaff = AgentFrontStaff::findOne($staff_id);
- $front_agent_admin_id = $agentFrontStaff->front_agent_admin_id;
- }
- $line_order_key = DriverLineOrder::findOne(['line_id' => $line_order->line_id, 'sortkey' => $sortKey]);
- if ($line_order_key) {
- DriverLineOrder::updateAll(['sortkey' => $line_order->sortkey], [
- 'line_id' => $line_order_key->line_id,
- 'md_id' => $line_order_key->md_id
- ]);
- $md = Md::findOne($line_order_key->md_id);
- //增加操作日志(增加记录)
- AgentFrontStaffOperateLog::addOperateLog(
- AgentFrontStaffOperateLog::OPERATE_TYPE_SET_ROUTE,
- $staff_id,
- $front_agent_admin_id,
- $line_order->line_id,
- "修改配送顺序:投篮单号:" . $line_order_key->line_no . ';配送门店:' . $md->name . '(' . $line_order_key->md_id . ')' . ';顺序:' . $line_order->sortkey,
- );
- }
- DriverLineOrder::updateAll(['sortkey' => $sortKey], ['line_id' => $line_order->line_id, 'md_id' => $line_order->md_id]);
- $md = Md::findOne($line_order->md_id);
- //增加操作日志(增加记录)
- AgentFrontStaffOperateLog::addOperateLog(
- AgentFrontStaffOperateLog::OPERATE_TYPE_SET_ROUTE,
- $staff_id,
- $front_agent_admin_id,
- $line_order->line_id,
- "修改配送顺序:投篮单号:" . $line_order_key->line_no . ';配送门店:' . $md->name . '(' . $line_order->md_id . ')' . ';顺序:' . $sortKey,
- );
- $t->commit();
- return [
- 'code' => 0,
- 'msg' => '操作成功'
- ];
- } catch (\Exception $e) {
- $t->rollBack();
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- /**
- * 查询司机绑定门店列表
- */
- public function bindMdList() {
- try {
- $driver_id = $this->driver_id;
- $tel = $this->tel;
- $name = $this->name;
- $open_status = $this->open_status;
- $query = DriverMdBind::find()->alias('dm')->leftJoin(['m' => Md::tableName()], 'dm.md_id=m.id')
- ->where(['dm.is_delete' => 0, 'm.is_delete' => 0, 'driver_id' => $driver_id]);
- if (!empty(trim($name))) {
- $query->andWhere(['like', 'm.name', $name]);
- }
- if (!empty(trim($tel))) {
- $query->andWhere(['like', 'm.mobile', $tel]);
- }
- if ($open_status !== null && in_array($open_status, [0, 1])) {
- // 不知道数据库能不能直接对时间进行比较 按照网上教程来直接进行比较 测试没啥问题
- $time = date('H:i');
- $query->andWhere(['m.open_status' => $open_status]);
- if ($open_status) {
- $query->andWhere(['AND', ['<', 'start_time', $time], ['>', 'end_time', $time]]);
- } else {
- $query->andWhere(['OR', ['>', 'start_time', $time], ['<', 'end_time', $time]]);
- }
- }
- $query->select('dm.id, m.id as md_id, m.name, m.mobile, m.address, m.cover_url,
- m.province, m.city, m.district, dm.created_at, m.open_status, m.start_time,
- m.end_time')->orderBy('dm.created_at DESC');
- $list = pagination_make($query);
- foreach ($list['list'] as $index => &$item) {
- $item['open_status'] = intval($item['open_status']);
- //是否打烊 根据时间判断一下
- if (!empty(trim($item['start_time'])) && !empty(trim($item['end_time']))) {
- $start_time = date('Y-m-d ' . $item['start_time']);
- $end_time = date('Y-m-d ' . $item['end_time']);
- if (time() < strtotime($start_time) || time() > strtotime($end_time)) {
- $item['open_status'] = 0;
- }
- }
- $item['created_at'] = date('Y-m-d H:i:s', $item['created_at']);
- $district = District::find()->where(['id' => [$item['province'], $item['city'], $item['district']]])
- ->select('name')->column();
- $item['address'] = implode(' ', $district) . $item['address'];
- }
- $md_list = AgentFrontBind::getAgentFrontBindMdList(get_admin()->id);
- $md_id_list = array_column($md_list, 'id');
- $driverMdBind = DriverMdBind::find()->where(['is_delete' => 0, 'md_id' => $md_id_list])
- ->select('md_id')->column();
- $md_id_list = array_diff($md_id_list, $driverMdBind);
- $list['md_list'] = Md::find()->where(['id' => $md_id_list])->select('id, name')->asArray()->all();
- return [
- 'code' => 0,
- 'msg' => 'ok',
- 'data' => $list
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- /**
- * 仓库司机绑定门店
- */
- public function driverBindMd() {
- try {
- $driver_id = $this->driver_id;
- $md_id = $this->md_id;
- $form = new DriverMdBind();
- $form->md_id = $md_id;
- $form->driver_id = $driver_id;
- if (!$form->save()) {
- throw new \Exception(implode(';', array_values($form->firstErrors)));
- }
- return [
- 'code' => 0,
- 'msg' => '绑定成功'
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- /**
- * 删除司机绑定门店
- */
- public function deleteDriverBind() {
- try {
- $ids = explode(',', $this->ids);
- foreach ($ids as $id) {
- $model = DriverMdBind::findOne($id);
- if (!$model) {
- throw new \Exception('记录不存在');
- }
- if (intval($model->is_delete)) {
- throw new \Exception('记录已删除');
- }
- $model->is_delete = 1;
- if (!$model->save()) {
- throw new \Exception(implode(';', array_values($model->firstErrors)));
- }
- }
- return [
- 'code' => 0,
- 'msg' => '操作成功'
- ];
- } catch (\Exception $e) {
- return [
- 'code' => 1,
- 'msg' => $e->getMessage()
- ];
- }
- }
- public function geocoder($address = ''){
- $tencent_map_key = Option::get('tencent_map_key', 0, 'saas', '')['value'];
- $url = 'https://apis.map.qq.com/ws/geocoder/v1/?';
- $params = [
- 'key' => $tencent_map_key,
- 'address' => $address,
- ];
- $url .= http_build_query($params);
- $json = file_get_contents($url);
- $res = json_decode($json, true);
- if($res['status'] == 0 && $res['result']['location']){
- return $res['result']['location'];
- }
- return ['lng' => '', 'lat' => ''];
- }
- public function distanceMatrix($from = '39.071510,117.190091', $to = '39.071510,117.190091;40.007632,116.389160'){
- $url = 'https://apis.map.qq.com/ws/distance/v1/matrix?';
- $tencent_map_key = Option::get('tencent_map_key', 0, 'saas', '')['value'];
- $params = [
- 'key' => $tencent_map_key,
- 'from' => $from,
- 'to' => $to,
- 'mode' => 'driving',
- ];
- $url .= http_build_query($params);
- // var_dump($url);
- $json = file_get_contents($url);
- // var_dump($json);
- // $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}]}]}}';
- $res = json_decode($json, true);
- if($res['status'] == 0 && $res['result']['rows'][0]['elements']){
- return $res['result']['rows'][0]['elements'];
- }
- return null;
- }
- //腾讯接口距离排序
- public function sortDistance($from, $to) {
- $matrix = $this->distanceMatrix($from, $to);
- // var_dump($matrix);die;
- if(!$matrix){
- throw new \Exception('距离排序错误');
- }
- $res = [];
- foreach ($matrix as $i => $item) {
- $res['a'.$i] = $item['duration'];
- }
- // var_dump($res);
- asort($res);
- // var_dump($res);
- return $res;
- }
- //本地距离排序
- public function sortDistanceLoc($from, $to) {
- $to = explode(';', $to);
- $res = [];
- foreach($to as $i => &$item){
- $item = explode(',', $item);
- $item[2] = $i;
- }
- $from = explode(',', $from);
- $point1 = $from;
- while(count($to)){
- $dist1 = 99999;
- $t = 0;
- foreach ($to as $i => $point2) {
- $dist = $this->distance($point1, $point2);
- if($dist < $dist1){
- $dist1 = $dist;
- $t = $i;
- }
- }
- $point1 = $to[$t];
- $res[] = $to[$t];
- unset($to[$t]);
- }
- $res2 = [];
- foreach($res as $item){
- $res2['a' . $item[2]] = 1;
- }
- return $res2;
- }
- public function distance($point1, $point2) {
- $x = abs($point2[0] - $point1[0]);
- $y = abs($point2[1] - $point1[1]);
- return $x * $x + $y * $y;
- }
- }
|