派单系统(灵活使用模型)

<?php
if (!defined('BASEPATH')) {
    exit('No direct script access allowed');
}
/* v3.1.0  */
class Dispatch extends M_Controller
{    
    
    public function init()
    {
        
        //1.查询出满足派单条件的所有订单(支付完成 || 货到付款 || 工单下单 && 不是买桶单 && 送达时间与现在时间相比小于1小时)=>没有人接单的订单
	    $oids = $this->db->select('id')
	        ->where('arrive_time<',time()+60*60) 
	        ->where('dispatch_degree<',5)
	        ->where('buy_bucket_type!=',1)//非买桶订单
	        ->where('execute_times<=',time())
	        ->where('(pay_status=3 or order_type=1 or order_status=3 or order_type=2 or back_bucket_type=2 )')
	        ->order_by('id', 'asc')->order_by('dispatch_times', 'asc')->limit(100)->get('imt_1_order')->result_array();
	    
        $oids = array_column($oids, 'id');
        
        if($oids){
            $this->db->where_in('id', $oids)->set('dispatch_times', 'dispatch_times+1', false)->update('1_order');//派单次数
        }
        
        return $oids;
    }
    
    //定时请求该方法(corntab)
    public function index()
    {   
        $token = '3d1084d448c51c6dbfdb661932518e';
        if ($token != $_GET['token']) {
            echo '非法数据来源';
            exit;
        }
        $this->load->model('dispatch_model');//加载派单模型
        $oids = $this->init(); //派单初始化
        foreach ($oids as $oid) {
            $bundling_uid = $this->bundlingUid($oid);  //是否绑定
            $pretreatment = $this->pretreatment($oid, $bundling_uid);//派单预处理(系统核心)
            $newuids_1 = $pretreatment[0];$newuids_2 = $pretreatment[1];$newuids_3 = $pretreatment[2];
            if($bundling_uid > 0){ //1.1有绑定的人
                $prognosis = $this->prognosis($oid, $bundling_uid);//绑定预处理
                $member = $prognosis[0];
                $available = $prognosis[1];
                if ($member['employ_status'] == 1 && $member['state'] == 0 && $available == 1) { //是否满足绑定
                    $dispatch_degree = dr_imt_1_order($oid)[0]['dispatch_degree']; //如果订单深度已经是1就往下走
                    if($dispatch_degree<1){
                        $this->dispatch_model->update_execute_time($oid,dr_var("bundlingModel"));//如果满足绑定模式,标记该订单的下次执行时间
                        $this->bundlingModel($oid, array($bundling_uid));
                    }else{
                        $this->judgeModelFirst($oid,$newuids_1,$newuids_2,$newuids_3);
                    }
                }else{
                    $this->judgeModelFirst($oid,$newuids_1,$newuids_2,$newuids_3);
                }
            }else{
                $this->judgeModelFirst($oid,$newuids_1,$newuids_2,$newuids_3);
            }
        }
        echo 'index sql查询次数:' . $this->db->total_queries() . "<br>";
    }
    
    //判断是否有绑定派单员
    public function bundlingUid($oid)
    {
        //判断该订单的下单者是否有绑定派单员(判断会员主表中是否有pid)=>pid只能是送水员
        $buy_uid = $this->db->select('buy_uid')->get_where("imt_1_order", array('id' => $oid))->row_array()['buy_uid'];
        //查询该订单的下单者是否有分销上级(派单员)
        $bundling_uid = $this->db->select('pid')->get_where("imt_member", array('uid' => $buy_uid))->row_array()['pid'];
        echo 'bundlingUid sql查询次数:' . $this->db->total_queries() . "<br>";
        return $bundling_uid;
    }
    
    //判断该绑定的派单员是否满足所有条件
    public function prognosis($oid, $bundling_uid)
    {
        //3.1获取该派单员所有的信息(是否在职,是否是工作状态,是否满足可配送商品)
        $bundling_member = dr_member_info($bundling_uid);
        $cids = $this->db->select('cid')->get_where("imt_1_order_goods", array('oid' => $oid))->result_array();
        $new_order_type = dr_imt_1_order($oid)[0]['new_order_type'];//oliver queen 2.15 如果是桶订单
        if ($cids) {
            foreach ($cids as $cid) {
                $cidsNew[] = $cid['cid'];
            }
            //可配送商品ids与该订单包含的商品ids进行匹配
            $goods = $this->db->select('goods_available')->get_where("imt_member_data", array('uid' => $bundling_uid))->row_array()['goods_available'];
            $goodsNew = explode(',', $goods);
            if (empty(array_diff($cidsNew, $goodsNew))) {
                $available = 1;
            } else {
                $available = 0;
            }
        }else {
            if ($new_order_type == 1) {
                //桶商品跳过可配送商品
                $available = 1;
                //满足可配送商品
            }else{
                $available = 0;
            }
        }
        echo 'prognosis sql查询次数:' . $this->db->total_queries() . "<br>";
        return array($bundling_member, $available);
    }
    
    //绑定模式
    public function bundlingModel($oid, $dispatch_degree=1,$bundling_uid)
    {
        $this->dispatch_model->update_order_level($oid, $dispatch_degree);
        $this->dispatch_model->update_level_record($oid, $dispatch_degree);
        $this->dispatch_model->update_auth_record($oid, $dispatch_degree, $bundling_uid);
        echo 'bundlingModel sql查询次数:' . $this->db->total_queries() . "<br>";
    }
    
    //预处理(派单系统核心)
    public function pretreatment($oid,$bundling_uid)
    {   
        $actual_order = reset(dr_imt_1_order($oid)); //订单信息
        $cids = $this->db->select('cid')->get_where("imt_1_order_goods", array('oid' => $oid))->result_array();
        $cids = array_column($cids, 'cid');
        $section = square_section($actual_order['point_lng'], $actual_order['point_lat'], dr_var("radius"));//匹配半径全局变量
        $new_order_type = $actual_order['new_order_type'];//订单类型(桶订单1与商品订单0)
        
        if($new_order_type){
            //桶订单(不考虑可满足商品)
            //查出满足所有条件的会员信息(会员附表所有数据)
            $members=$this->db->where("(point_map_lng between {$section['left']} and {$section['right']})")->where("(point_map_lat between {$section['bottom']} and {$section['top']})")
                 ->where('state', 0)->where('employ_status', 1)
                 ->get('member_data')->result_array();
            //满足条件的所有人
            if ($members) {
                $members_main = $this->db->where_in('uid', array_column($members,'uid'))->get('member')->result_array();
                $members_main = array_column($members_main, null, 'uid'); //(会员主表所有数据)
            } else {
                $members_main = [];
            }
        }else{
            //商品订单(考虑可满足商品)
            //x.1查询所有在10公里范围内的 在职 在线 商品满足 的所有派单员
            $this->db->where("(point_map_lng between {$section['left']} and {$section['right']})")->where("(point_map_lat between {$section['bottom']} and {$section['top']})")
                 ->where('state', 0)->where('employ_status', 1);
            //x.2 满足可匹配商品
            if ($cids) {
                foreach ($cids as $cid) {
                    $this->db->where("FIND_IN_SET({$cid}, goods_available)");
                }
            }
            $members = $this->db->get('member_data')->result_array();
            if ($members) {
                $members_main = $this->db->where_in('uid', array_column($members,'uid'))->get('member')->result_array();
                $members_main = array_column($members_main, null, 'uid');
            } else {
                $members_main = [];
            }
        }
        
        //查询所有派单员的综合分
        //x.3查询派单员的分数
        foreach ($members as $member) {
            $newid_pre = $member['uid']; //当前uid
            $newid_pre_member = $member + $members_main[$member['uid']];//当前uid所有的信息
            $newid_score[$newid_pre] = $newid_pre_member['zonghefen']*10 + (100 - round(dr_distance($actual_order['point_lat'], $actual_order['point_lng'], $newid_pre_member['point_map_lat'], $newid_pre_member['point_map_lng']))/100)/2;
        }
        
        //x.4按照派单员的分数划层级(最终的预处理池子)
        foreach ($newid_score as $key => $value) {
            if ($value >= 80) {
                $newid_score_value[1][$key] = $value;
            } elseif ($value >= 60) {
                $newid_score_value[2][$key] = $value;
            } else {
                $newid_score_value[3][$key] = $value;
            }
        }
        
        //x.5按照派单员的分数划层级(最终的预处理池子)
        $newuids_1 = $newuids_2 = $newuids_3 = [];
        foreach ($newid_score_value[1] as $key => $value) {
            $newuids_1[] = $key;
            //80-100分
        }
        
        array_push($newuids_1, $bundling_uid);
        
        foreach ($newid_score_value[2] as $key => $value) {
            $newuids_2[] = $key;
            //60-80分
        }
        foreach ($newid_score_value[3] as $key => $value) {
            $newuids_3[] = $key;
            //0-60分
        }
        
        //x.6抢单记录日志
        //$this->grabRecord($newuids_1,$newuids_2,$newuids_3,$oid);
        
        //x.6数组追加(基于原有可查看uids,进一步扩展)
        if (count($newuids_1) > 0 && count($newuids_2) > 0) {
            $newuids_2 = array_merge($newuids_1, $newuids_2);
        } elseif (count($newuids_2) == 0) {
            $newuids_2 = $newuids_1;
        }
        if (count($newuids_2) > 0 && count($newuids_3) > 0) {
            $newuids_3 = array_merge($newuids_2, $newuids_3);
        } elseif (count($newuids_3) == 0) {
            $newuids_3 = $newuids_2;
        }
        
        echo 'pretreatment sql查询次数:' . $this->db->total_queries() . "<br>";
        return array($newuids_1, $newuids_2, $newuids_3);
    }
    
    //1级抢单模式
    public function grabModelFirst($oid,$dispatch_degree,$newuids_1)
    {
        $this->dispatch_model->update_order_level($oid,$dispatch_degree);
        $this->dispatch_model->update_auth_record($oid,$dispatch_degree,$newuids_1);
        echo 'grabModelFirst sql查询次数:' . $this->db->total_queries() . "<br>";
    }
    
    //2级抢单模式
    public function grabModelSecond($oid,$dispatch_degree,$newuids_2)
    {
        $this->dispatch_model->update_order_level($oid,$dispatch_degree);
        $this->dispatch_model->update_auth_record($oid,$dispatch_degree,$newuids_2);
        echo 'grabModelSecond sql查询次数:' . $this->db->total_queries() . "<br>";
    }
    
    //3级抢单模式
    public function grabModelThird($oid,$dispatch_degree,$newuids_3)
    {
        $this->dispatch_model->update_order_level($oid,$dispatch_degree);
        $this->dispatch_model->update_auth_record($oid,$dispatch_degree,$newuids_3);
        echo 'grabModelThird sql查询次数:' . $this->db->total_queries() . "<br>";
    }
    
    //手动派单模式
    public function manualModel($oid,$dispatch_degree)
    {   
        $this->dispatch_model->update_order_level($oid,$dispatch_degree);
        echo 'manualModel sql查询次数:' . $this->db->total_queries() . "<br>";
    }
    
    //1级判断模式
    public function judgeModelFirst($oid,$newuids_1,$newuids_2,$newuids_3){

        if($newuids_1){
            //7.1订单派单深度是否小于2
            $dispatch_degree = dr_imt_1_order($oid)[0]['dispatch_degree']; //如果订单深度已经是2就往下走
            if($dispatch_degree<2){
                $this->dispatch_model->update_execute_time($oid,dr_var("grabModelFirst"));//如果满足1级绑定模式,标记该订单的下次执行时间
                $this->grabModelFirst($oid, 2, $newuids_1); //执行一级抢单
            }else{
                $this->judgeModelSecond($oid,$newuids_1,$newuids_2,$newuids_3);
            }
        }else{
            $this->judgeModelSecond($oid,$newuids_1,$newuids_2,$newuids_3);
        }
    }
    
    //2级判断模式
    public function judgeModelSecond($oid,$newuids_1,$newuids_2,$newuids_3){
       if($newuids_2){
            $dispatch_degree = dr_imt_1_order($oid)[0]['dispatch_degree']; //如果订单深度已经是3就往下走
            if($dispatch_degree<3){
                $this->dispatch_model->update_execute_time($oid,dr_var("grabModelSecond"));//如果满足2级绑定模式,标记该订单的下次执行时间
                $this->grabModelSecond($oid, 3, $newuids_2); //执行二级抢单
            }else{
                $this->judgeModelThird($oid,$newuids_1,$newuids_2,$newuids_3);
            }
        }else{
            $this->judgeModelThird($oid,$newuids_1,$newuids_2,$newuids_3);
        }
    }
    
    //3级判断模式
    public function judgeModelThird($oid,$newuids_1,$newuids_2,$newuids_3){
        if($newuids_3){
            $dispatch_degree = dr_imt_1_order($oid)[0]['dispatch_degree']; //如果订单深度已经是4就变指派
            //10.1 订单派单深度是否小于4
            if($dispatch_degree<4){
                $this->dispatch_model->update_execute_time($oid,dr_var("grabModelThird"));//如果满足3级绑定模式,标记该订单的下次执行时间
                $this->grabModelThird($oid, 4, $newuids_3); //执行三级抢单
            }else{
                //10.2 订单派单深度不小于4
                $this->manualModel($oid,5);
            }
        }else{
            //9.2 不满足三级
            $this->manualModel($oid,5);
        }
    }
}
<?php

if (!defined('BASEPATH')) exit('No direct script access allowed');
	
class Dispatch_model extends CI_Model {
	
	
    public function __construct() {
        parent::__construct();
	}
	
	/**
	 * 更新订单下次的可执行时间
	 *
	 * @param	intval	$oid	订单id
	 * @param	intval	$model	不同模式下设置的下次可执行时间
	 */
	 
	public function update_execute_time($oid,$model){
	    $this->db->where('id', $oid)->update('imt_1_order', array('execute_times' => time()+$model*60));//如果满足绑定模式,标记该订单的下次执行时间
	    debug_log($model);
	}
	
	/**
	 * 更新订单进度
	 *
	 * @param	intval	$oid	订单id
	 * @param	intval	$dispatch_degree	订单深度
	 */
	 
	public function update_order_level($oid,$dispatch_degree){
	    $this->db->where('id', $oid)->update('imt_1_order', array('dispatch_degree' => $dispatch_degree));
	}
	
	/**
	 * 记录订单的派单进度与派单员的关联关系
	 *
	 * @param	intval	$oid	订单id
	 * @param	intval	$dispatch_degree	订单深度
	 * @param	array	$uids	满足条件的uids
	 */
	 
	public function update_auth_record($oid,$dispatch_degree,$uids){
	    foreach ($uids as $uid) {
            $this->db->insert('imt_1_order_uid_record', array('dispatch_degree' => $dispatch_degree, 'uid' => $uid, 'availabl_time' => SYS_TIME, 'oid' => $oid));
        }
	}

}

 

No comments, so go and ...add one

Speak Your Mind

Your email address will not be published. Required fiels are marked *
You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>