<?php
 /** 
 * 美团配送api
 * @Copyright (C) 2018 汉潮 All rights reserved.
 * @License http://www.hanchao9999.com
 * @Author xiaogg <xiaogg@sina.cn>
 */
namespace Common\Vendor\Distribute;
class Meituan{
    private $config;
    private $url='https://peisongopen.meituan.com/api/';//api url地址
    private $is_sandbox=true;//是否为测试
    /**
     * 构造函数
     * @param array $config = array();
     */
    public function __construct($config){
        $this->config = !empty($this->config) && !empty($config)? array_merge($this->config, $config):!empty($config)?$config:$this->config;
        if(empty($this->config['app_key']))$this->is_sandbox=true;
        if($this->is_sandbox){
            $this->config['app_key']='e5936bacf0c54d2182319f5a60f248f5';
            $this->config['app_secret']='Kv(fI1Yay2MGgKs4!N>de~3S*{9+To@Gbi[[-nTCJZU_(d?bt>>T~MxGa*g0;OPF';
        }
        $this->siteappid=C('APPID');
    }
    /**
     * 新增订单
     * @param array(
     *      [order_sn]=>第三方订单ID不能为空,
     *      [goods_allmoney]=>订单金额不能为空,
     *      [receiver_name]=>收货人姓名不能为空,
     *      [receiver_address]=>收货人地址不能为空, 
     *      [receiver_lat]=>收货人地址维度不能为空, 
     *      [receiver_lng]=>收货人地址经度不能为空, 
     *      )
     */
    public function add_order($data){
        $data=$data[0];
        $return = array('status'=>0,'msg'=>'');if(empty($data)){return $return;}
        $save_data['distribute'] = 'Meituan';
        M('OrderInfo')->where(array('id'=>$data['order_id']))->save($save_data);        
        if($this->is_sandbox){$logistics='test_0001';}//测试环境
        else{
            $shop_id = $data["shop_id"];
            $logistics = M('Shops')->where(array('id'=>$shop_id))->getField('logistics');
            if(empty($logistics)){
                $return['msg'] = "第三方门店未注册";
                return $return;
            }
        }
        $notify_url=U('Home/Distribute/notify',array('apitype'=>'Meituan'),true,true);
        $notify_url=str_replace('index.php?s=/','',$notify_url);
        if(empty($data['tips']))$data['tips']=0.0;
        if(empty($this->config['param1']))$this->config['param1']=4011;
        $datas = array(
            'delivery_id'       => substr($this->siteappid.$data['order_sn'], 0,19),//配送标识
            'order_id'          => $data['order_sn'],//订单id
            'shop_id'           => $logistics,//门店id
            'delivery_service_code'=> $this->config['param1'],//飞速达:4002 快速达:4011 及时达:4012 集中送:4013            
            'receiver_name' => $data['consignee'],//收货人姓名
            'receiver_address'  => $data['province'].$data['city'].$data['district'].$data['address'],//收货人地址
            'receiver_phone'    => $data['mobile'],//	收货人手机号（手机号和座机号必填一项）
            'receiver_lat'      => $data['ypoint']*10000000,//收货人地址维度（高德坐标系）
            'receiver_lng'      => $data['xpoint']*10000000,//收货人地址经度（高德坐标系）
            'coordinate_type'   => 1,//坐标类型，0：火星坐标（高德，腾讯） 1：百度坐标
            'goods_value'       => $data['goods_allmoney'],//订单金额
            'goods_weight'      => format_decimal($data['cargo_weight']),//订单重量（单位：Kg）
            
            'poi_seq'           => $data['order_sn'],//门店订单流水号
            'note'              => $data['temp'],//订单备注
        );
        if(empty($datas['shop_id'])){$return['msg'] = '门店编号不能为空!';}
        if(empty($datas['order_id'])){$return['msg'] = '第三方订单ID不能为空!';}
        if(empty($datas['goods_value'])){$return['msg'] = '订单金额不能为空!';}
        if(empty($datas['receiver_name'])){$return['msg'] = '收货人姓名不能为空!';}
        if(empty($datas['receiver_address'])){$return['msg'] = '收货人地址不能为空!';}
        if(empty($datas['receiver_lat'])){$return['msg'] = '收货人地址纬度不能为空!';}
        if(empty($datas['receiver_lng'])){$return['msg'] = '收货人地址经度不能为空!';}
        if(empty($datas['receiver_phone'])){$return['msg'] = '收货人联系方式不能为空!';}
        if($return['msg'])return $return;
        //请求接口
        $reqStatus = $this->makeRequest($datas,'order/createByShop');
        if(empty($reqStatus['code'])){
            $return['status'] = 1;
            $return['info'] = $reqStatus['data'];
                        
            $map=array();
            $map['order_code']=$data['order_sn'];
            $map['marking']='Meituan';
            $count = M('TakeawayOrder')->where($map)->count();
            if($count<=0){
                $adds=array();
                $adds['client_id'] = $reqStatus['data']['mt_peisong_id'];
                $adds['order_code']=$data['order_sn'];
                $adds['order_id']  = $data['order_sn'];
                $adds['order_status'] = 1;
                $adds['update_time'] =$adds['add_time'] = NOW_TIME;     
                $adds['marking'] = 'Meituan';
                $adds['delivery_fee'] = idtoname($data['order_id'],'OrderInfo','delivery_fee','id',false);
                $adds['expire_time'] =NOW_TIME+(60*60*24*7);
                M('TakeawayOrder')->add($adds);
            }
            
        }else{
            $return['msg'] = $reqStatus["message"];
        }
        return $return;
    }
    /**
     * 重发订单
     */
    public function readd_order($data){        
        $datas = $data[0];
        $sav['is_delete'] = 1;
        M('TakeawayOrder')->where(array('order_code'=>$datas['order_sn']))->save($sav);
        return $this->add_order($data);
    }
    /**
     * 第三方回调
     */
    public function notify_order($data){
        $data=$data[0];
        if(!is_array($data)){parse_str($data,$data);}
        if(empty($data['order_id'])){$return=array('code'=>2);echo json_encode($return);}
        switch($data['status']){
            case 20:$order_status=2;break;
            case 30:$order_status=3;break;
            case 50:$order_status=4;break;
            case 99:$order_status=5;break;
            default:$order_status=1;break;
        }        
        $adds['client_id'] = $data['mt_peisong_id'];
        $adds['order_code'] = $data['order_id'];
        $adds['order_id'] = $data['order_id'];
        $adds['order_status'] = $order_status;
        $adds['update_time'] = NOW_TIME;
        if(!empty($data['courier_name']))$adds['dm_name'] = $data['courier_name'];
        if(!empty($data['courier_phone']))$adds['dm_mobile'] = $data['courier_phone'];
        if(!empty($data['cancel_reason']))$adds['cancel_reason'] = $data['cancel_reason'];
        /*$adds['accept_time'] = $adds['update_time'];*/
        $adds['marking'] = 'Meituan';
        $count = D('TakeawayOrder')->where('order_id='.$data['order_id'])->find();
        if(!$count){
            D('TakeawayOrder')->add($adds);
        }else{
            if($data['order_status'] == 3)$adds['fetch_time'] = NOW_TIME;//配送中时间
            if($data['order_status'] == 4){//已完成时间
                $adds['finish_time'] = NOW_TIME;
                $save_data['shipping_status'] = 4;
                $save_data['status'] = 3;
                $save_data['finish_time'] = NOW_TIME;
                M('OrderInfo')->where('order_sn='.$data['order_id'])->save($save_data);
            };
            if($data['order_status'] == 5)$adds['cancel_time'] = $adds['update_time'];//已取消时间
            if($data['order_status'] == 7)$adds['expire_time'] = $adds['update_time'];//已过期时间
            D('TakeawayOrder')->where('order_id='.$data['order_id'])->save($adds);
        }
        $return=array('code'=>0);
        echo json_encode($return);
    }
    /**
     * 订单详情查询
     * @param $order_id:第三方订单号
     *
     * @return status    响应状态，成功为"success"，失败为"fail"
     * @return code      响应返回吗，参考接口返回码
     * @return msg       响应描述
     * @return return    响应结果，JSON对象，详见具体的接口描述
     * @return errorCode 错误编码，与code一致
     */
    public function details_order($orderid){
        $return = array('status'=>0,'msg'=>'','info'=>array());
        $orderid = $orderid[0];
        $mt_peisong_id=idtoname($orderid,'TakeawayOrder','client_id','order_code');
        $data = array(
            'delivery_id'=> substr($this->siteappid.$orderid, 0,19),
            'mt_peisong_id'=> $mt_peisong_id
        );
        //请求接口
        $reqStatus = $this->makeRequest($data,'order/status/query');
        if(empty($reqStatus['code'])){
            $return['info'] = $reqStatus['data'];
            $return['info']['code']=$reqStatus['data']['status'];
            $orderstatus=$this->getorderstatus($reqStatus['data']['status']);if(empty($orderstatus) || is_array($orderstatus))$orderstatus="待接单";
            $return['info']['statusMsg']=$orderstatus;            
            $return['info']['transporterName'] = $reqStatus['data']['courier_name'];
            $return['info']['transporterPhone'] = $reqStatus['data']['courier_phone'];
            $timefields=array(0=>'createTime',20=>'acceptTime',30=>'fetchTime',50=>'finishTime',90=>'cancleTime');
            $timefield=$timefields[$reqStatus['data']['status']];
            if(!empty($timefield)){
                $return['info'][$timefield] = time_format($reqStatus['data']['operate_time']);
            }
        }else{
            $return['status'] = 1;
            $return['msg'] = $reqStatus['message'];
        }
        return $return;
    }
    
    /**
     * 模拟订单状态
     * @param $order_id:第三方订单号
     */
    public function status_order($data){
        $data = $data[0];$return = array('status'=>0,'msg'=>'');
        $mt_peisong_id=idtoname($data["order_id"],'TakeawayOrder','client_id','order_code');
        $datas = array(
            'delivery_id'=> $this->siteappid.$data["order_id"],
            'mt_peisong_id'=> $mt_peisong_id,
        );
        $request=array(
            1=>'test/order/arrange',//模拟接单
            2=>'test/order/pickup',//模拟取货
            3=>'test/order/deliver',//模拟送达
            4=>'test/order/rearrange',//模拟改派
            5=>'test/order/reportException',//模拟上传异常
        );
        $url=$request[$data["status"]];
        if(empty($url)){
            $return['msg']='测试方法不存在';return $return;
        }
        //请求接口
        $reqStatus = $this->makeRequest($datas,$url);
        return $reqStatus;
    }
    /**
     * 取消订单
     * @param $order_id:第三方订单号,取消原有id
     * @param $cancel_reason_id:取消缘由id
     * @param cancel_reason 取消原因
     */
    public function cancel_order($data){
        $data = $data[0];
        $return = array('status'=>0,'msg'=>'','info'=>array());
        $mt_peisong_id=idtoname($data["order_id"],'TakeawayOrder','client_id','order_code');
        if(empty($data["cancel_reason_id"]))$data["cancel_reason_id"]=399;
        if(empty($data["cancel_reason"]))$data["cancel_reason"]=$this->getcanclestatus($data["cancel_reason_id"],3);
        if(empty($data["cancel_reason"]))$data["cancel_reason"]='其他原因';
        
        $data = array(
            'delivery_id'=> $this->siteappid.$data["order_id"],
            'mt_peisong_id'=> $mt_peisong_id,
            'cancel_reason_id'=> $data["cancel_reason_id"],
            'cancel_reason'=> $data["cancel_reason"],
        );
        //请求接口
        $reqStatus = $this->makeRequest($data,'order/delete');
        if(empty($reqStatus['code'])){
            $return['info'] =$reqStatus['data'];
        }else{
            $return['status'] = 1;
            $return['msg'] = $reqStatus['message'];
        }       
        return $return;
    }
    /**
     * 新增门店
     */
    public function shop_add($postdata){
        $return = array('status'=>0,'msg'=>'');
        $postdata = $postdata[0];
        $shops_location = M('Shops')->where(array('status'=>1,'id'=>$postdata['id']))->getField('logistics');
        if(!empty($shops_location)){
            $return['status'] = 1;
            return $return;
        }
        $sav["logistics"] = $postdata['id'];
        $res = M('Shops')->where(array('id'=>$postdata['id']))->save($sav);        
        if($res){
            $return['status'] = 1;
            $return['msg'] = "添加成功";
        }else{
            $return['msg'] ='添加失败';
        }
        return $return;
    }
    public function shop_update($postdata){
        $return = array('status'=>1,'msg'=>'');return $return;
    }
    /**
     * 请求调用api
     * data:业务数据
     * @return bool
     */
    private function makeRequest($data,$url){
        $base=array(
            'appkey'=>$this->config['app_key'],
            'timestamp'=>NOW_TIME,
            'version'=>'1.0',
        );
        $param =array_merge($base,$data);
        $param["sign"]=$this->generateSign($param);
        $request=$this->url.$url;
        $request = curlget($request,$param,'POST');
        $request = trim($request);
        $request = json_decode($request,1);
        return $request;
    }
    private function getorderstatus($code=''){
        $status=array(
            0=>'待调度',
            20=>'已接单',
            30=>'已取货',
            50=>'已送达',
            99=>'已取消'
        );
        return $code?$status[$code]:$status;
    }
    private function getcanclestatus($code='',$type=1){
        $status[1]=array(
            101=>'顾客主动取消',
            102=>'顾客更改配送时间/地址',
            103=>'备货、包装、货品质量问题取消',
            199=>'其他接入方原因',
            201=>'配送服务态度问题取消',
            202=>'骑手配送不及时',
            203=>'骑手取货不及时',
            299=>'其他美团配送原因',
            399=>'其他原因');
         $status[2]=array(
            1110=>'取货地址超区',
            1111=>'送货地址超区',
            1199=>'其他接入方原因',
            1201=>'当前运力紧张，暂无骑手接单，建议稍后重新发单',
            1202=>'因骑手原因，订单被取消',
            1203=>'因系统原因，订单被取消，建议稍后重新发单',
            1299=>'其他美团配送原因',
            1399=>'其他原因');
        if($type==3 && $code){
            if(!empty($status[1][$code]))return $status[1][$code];
            if(!empty($status[2][$code]))return $status[2][$code];
        }
        return $code?$status[$type][$code]:$status[$type];
    }
    //生成签名
    protected function generateSign($params){
        $stringToBeSigned = $this->paramsToString($params);
		return sha1($stringToBeSigned);
	}
    //验签
	protected function verifySign($params){
	    $sign = $params["sign"];unset($params["sign"]);
        $stringToBeSigned = $this->paramsToString($params);        
        if(!empty($sign)){return $sign == sha1($stringToBeSigned);}
        return false;
	}
    //组合待签名字符
    protected function paramsToString($params){
        $params=array_filter($params);
		ksort($params);
        $sortedString = $this->config["app_secret"];
        foreach($params as $k=>$v){
            $sortedString.=$k.$v;
        }
        return $sortedString;
    }
}
?>