<?php
// +----------------------------------------------------------------------
// | likeadmin快速开发前后端分离管理后台(PHP版)
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | 开源版本可自由商用,可去除界面版权logo
// | gitee下载:https://gitee.com/likeshop_gitee/likeadmin
// | github下载:https://github.com/likeshop-github/likeadmin
// | 访问官网:https://www.likeadmin.cn
// | likeadmin团队 版权所有 拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeadminTeam
// +----------------------------------------------------------------------

namespace app\api\logic;

use app\common\logic\BaseLogic;
use app\common\model\logistics\Courier;
use app\common\model\logistics\Logistics;
use app\common\model\logistics\Merchant;
use app\common\model\logistics\Order;
use app\common\model\logistics\Product;
use app\common\model\logistics\LogisticsRecord;
use app\common\model\logistics\User;
use app\common\model\vehicle\Company;
use think\facade\Log;


/**
 * 物流逻辑
 * Class LogisticsLogic
 * @package app\api\logic
 */
class LogisticsLogic extends BaseLogic
{
    /*
     * 物流列表
     * @param $params
     * @return array
     */
    public static function list($params):array {
        //获取物流列表
        if($params['user_type'] == 0){
            $user = ['courier_id','=',$params['user_id']];
        }else{
            $user = ['captain_id','=',$params['user_id']];
        }
        if(!isset($params['status'])){
            $status = ['status','in','0,1'];
        }elseif($params['status'] == 2){
            $status = ['status','in','2,3'];
        }else{
            $status = ['status','in',$params['status']];
        }
        $logistics = Logistics::where([$user])
                    ->where([$status])
                    ->where('(order_sn LIKE "%'.$params['keywords'].'%" OR shop_phone LIKE "%'.$params['keywords'].'%" OR shop_name LIKE "%'.$params['keywords'].'%" OR receiver_phone LIKE "%'.$params['keywords'].'%" OR receiver_name LIKE "%'.$params['keywords'].'%")')
                    ->order('update_time desc')
                    ->paginate([
                        'list_rows'=> !empty($params['page_size'])? $params['page_size'] : 6,
                        'page' => !empty($params['page_num'])? $params['page_num'] : 1,
                    ])->each(function($lst_item){
                        $lst_item['status_name'] = $lst_item->status_name;
                        $product_count = 0;
                        //获取产品信息
                        $lst_item['products'] = Product::field('product_num,cart_info')->where('order_id', $lst_item['order_id'])->select()->each(function($pro_item) use(&$product_count){
                            $pro_item['cart_info'] = json_decode($pro_item['cart_info'], true);
                            $pro_item['goods_name'] = $pro_item['cart_info']['product']['store_name'];
                            $pro_item['goods_unit'] = $pro_item['cart_info']['product']['unit_name'];
                            $product_count += $pro_item['product_num'];
                            unset($pro_item['cart_info']);
                            return $pro_item;
                        });
                        $lst_item['product_count'] = $product_count;
                        return $lst_item;
                    })->toArray();
        //返回数据
        return $logistics;
    }

    /*
     * 配送端物流详情
     * @param $id
     * @return array
     */
    public static function cDetail($id):array {
        //获取物流信息
        $logistics = Logistics::field('id,order_id,order_sn,shop_name,shop_user,shop_phone,shop_address,shop_long,shop_lat,receiver_name,receiver_phone,receiver_address,status,create_time')
                    ->where('id', $id)->find();
        //获取商品信息
        $product_count = 0;
        $product = Product::field('product_num,cart_info')->where('order_id', $logistics['order_id'])->select()->each(function($pro_item) use(&$product_count){
            $pro_item['cart_info'] = json_decode($pro_item['cart_info'], true);
            $pro_item['goods_name'] = $pro_item['cart_info']['product']['store_name'];
            $pro_item['goods_unit'] = $pro_item['cart_info']['product']['unit_name'];
            $product_count += $pro_item['product_num'];
            unset($pro_item['cart_info']);
            return $pro_item;
        })->toArray();
        //获取物流记录
        $records = LogisticsRecord::field('type,user_name,content,create_time')
                   ->where('lst_id', $logistics['id'])->order('create_time desc')->select()->each(function($red_item){
                        switch ($red_item['type']) {
                            case 1:
                                $red_item['content'] = '用户'.$red_item['user_name'].$red_item['content'];
                                break;
                            case 2:
                                $red_item['content'] = '配送员'.$red_item['user_name'].$red_item['content'];
                                break;
                            case 3:
                                $red_item['content'] = '平台'.$red_item['user_name'].$red_item['content'];
                                break;
                            default:
                                $red_item['content'] = '未知';
                        }
                        unset($red_item['type'], $red_item['user_name']);
                   })->toArray();
        //返回数据
        return[
            'logistics' => $logistics,
            'product' => $product,
            'product_count' => $product_count,
            'record' => $records,
        ];
    }

    /*
     * 商超用户物流详情
     * @param $params
     * @return array
     */
    public static function uDetail($params):array {
        //获取物流信息
        $logistics = Logistics::field('id,order_id,order_sn,courier_name,courier_phone,shop_name,shop_user,shop_phone,shop_address,receiver_name,receiver_phone,receiver_address,status,create_time')
            ->where('order_id', $params['order_id'])->where('order_sn',$params['order_sn'])->find();
        //获取物流记录
        $records = LogisticsRecord::field('type,user_name,content,create_time')
            ->where('lst_id', $logistics['id'])->order('create_time desc')->select()->each(function($red_item){
                switch ($red_item['type']) {
                    case 1:
                        $red_item['content'] = '用户'.$red_item['user_name'].$red_item['content'];
                        break;
                    case 2:
                        $red_item['content'] = '配送员'.$red_item['user_name'].$red_item['content'];
                        break;
                    case 3:
                        $red_item['content'] = '平台'.$red_item['user_name'].$red_item['content'];
                        break;
                    default:
                        $red_item['content'] = '未知';
                }
                unset($red_item['type'], $red_item['user_name']);
            })->toArray();
        //返回数据
        return[
            'logistics' => $logistics,
            'record' => $records,
        ];
    }

    /*
     * 生成物流信息
     * @param $params
     * @return array
     */
    public static function create($params):array {
        //判断物流信息是否已存在
        $logistics = Logistics::where('order_id', $params['order_id'])->where('order_sn', $params['order_sn'])->find();
        if($logistics) return ['code'=>0, 'msg'=>'物流信息已存在'];
        //查找订单信息
        $order = Order::alias('s')->where('order_id', $params['order_id'])->where('order_sn', $params['order_sn'])->find();
        if(empty($order['user_address_code'])) return ['code'=>0, 'msg'=>'用户地址信息错误'];
        //查找商家信息
        $shop = Merchant::field('mer_id,mer_name,real_name,mer_phone,mer_address,long,lat')->where('mer_id',$order['mer_id'])->find();
        //获取队长用户信息
        $captain = Courier::field('id,company_id,nickname,mobile')->where("CONCAT_WS(',',province,city,area,street,village,brigade) = '". $order['user_address_code']."'")->where('is_captain',1)->find();
        if(!$captain) return ['code'=>0, 'msg'=>'无法确定所在小队'];
        //获取配送员信息
        $courier = Company::field('company_name,user_id,master_name,master_phone')->where('id',$captain['company_id'])->find();
        //判断配送员是否存在
        if(!$courier) return ['code'=>0, 'msg'=>'配送员未匹配'];
        //获取下单用户信息
        $orderUser = User::field('uid,nickname,phone')->where('uid', $order['uid'])->find();
        //写入数据
        Logistics::startTrans();
        try {
            $lst = Logistics::create([
                'order_id' => $params['order_id'],
                'order_sn' => $params['order_sn'],
                'status' => 0,
                'user_id' => $orderUser['uid'],
                'user_name' => $orderUser['nickname'],
                'user_phone' => $orderUser['phone'],
                'captain_id' => $captain['id'],
                'captain_name' => $captain['nickname'],
                'captain_phone' => $captain['mobile'],
                'courier_id' => $courier['user_id'],
                'courier_name' => $courier['master_name'],
                'courier_phone' => $courier['master_phone'],
                'courier_company' => $courier['company_name'],
                'shop_id' => $shop['mer_id'],
                'shop_name' => $shop['mer_name'],
                'shop_user' => $shop['real_name'],
                'shop_phone' => $shop['mer_phone'],
                'shop_address' => $shop['mer_address'],
                'shop_long' => $shop['long'],
                'shop_lat' => $shop['lat'],
                'receiver_name' => $order['real_name'],
                'receiver_phone' => $order['user_phone'],
                'receiver_address' => $order['user_address'],
                'receiver_take_code' => 0,
                'create_time' => time(),
                'update_time' => time(),
                'delete_time' => 0,
                'qh_time' => 0,
                'ps_time' => 0,
                'qx_time' => 0,
            ]);
            LogisticsRecord::create([
                'lst_id' => $lst->id,
                'type' => 1,
                'user_name' => $orderUser['nickname'],
                'user_phone' => $orderUser['phone'],
                'content' => '已提交订单',
                'create_time' => time(),
            ]);
            Logistics::commit();
        } catch (\Exception $e) {
            Logistics::rollback();
            return ['code'=>0, 'msg'=>$e->getMessage()];
        }
        //推送消息
        $register_id = Courier::field('register_id')->where('id',$courier['user_id'])->find();
        if($register_id && !empty($register_id['register_id'])){
            $push_result = push_message($register_id['register_id'],'您有一条新的配送任务,请尽快处理!!');
            if($push_result['code'] == 0) {
                Log::write('["极光推送:"]'.$push_result['msg'],'error');
            }
        }
        return ['code'=>1, 'msg'=>'操作成功','data'=>['nickname'=>$courier['master_name'],'phone'=>$courier['master_phone']]];
    }

    /*
     * 配送员接单
     * @param $params
     * @return array
     */
    public static function takeGoods($params):array {
        //获取物流信息
        $logistics = Logistics::where('id', $params['logistics_id'])->find();
        if (!$logistics) return ['code'=>0, 'msg'=>'物流信息不存在'];
        //判断订单是否一致
        if($logistics['order_id'] != $params['order_id'] || $logistics['order_sn'] != $params['order_sn']) return ['code'=>0, 'msg'=>'订单信息不一致'];
        //判断物流信息状态
        switch ($logistics['status']) {
            case 1:
                return ['code'=>0, 'msg'=>'该商品正在配送中'];
            case 2:
                return ['code'=>0, 'msg'=>'该商品已完成配送'];
            case 3:
                return ['code'=>0, 'msg'=>'该订单已经被取消'];
        }
        //更改物流信息状态
        Logistics::startTrans();
        try {
            //查询订单用户取件码
            $order = Order::field('logistics_code')->where('order_id', $params['order_id'])->where('order_sn', $params['order_sn'])->find();
            Logistics::where('id', $params['logistics_id'])->update([
                'status' => 1,
                'update_time' => time(),
                'qh_time' => time(),
                'receiver_take_code' => $order['logistics_code']
            ]);
            LogisticsRecord::create([
                'lst_id' => $logistics['id'],
                'type' => 2,
                'user_name' => $logistics['courier_name'],
                'user_phone' => $logistics['courier_phone'],
                'content' => '已提取商品',
                'create_time' => time(),
            ]);
            Logistics::commit();
        } catch (\Exception $e) {
            Logistics::rollback();
            return ['code'=>0, 'msg'=>$e->getMessage()];
        }
        //调用接口通知商超平台
        $url = env('project.shop_notify_domain').'/api/goods/take/'.$params['order_id'];
        curl_post($url,[],['order_sn'=>$params['order_sn']]);
        return ['code'=>1, 'msg'=>'操作成功'];
    }

    /*
     * 配送员配送
     * @param $params
     * @return array
     */
    public static function doneDelivery($params):array {
        //获取物流信息
        $logistics = Logistics::where('id', $params['logistics_id'])->find();
        if (!$logistics) return ['code'=>0, 'msg'=>'物流信息不存在'];
        //判断物流信息状态
        switch ($logistics['status']) {
            case 0:
                return ['code'=>0, 'msg'=>'该商品未揽件'];
            case 2:
                return ['code'=>0, 'msg'=>'该商品已配送'];
            case 3:
                return ['code'=>0, 'msg'=>'订单已被取消'];
        }
        //验证取件码
        if($logistics['receiver_take_code'] != $params['take_code']) return ['code'=>0, 'msg'=>'取件码错误'];
        //更改物流信息状态
        Logistics::startTrans();
        try {
            Logistics::where('id', $params['logistics_id'])->update([
                'status' => 2,
                'update_time' => time(),
                'ps_time' => time(),
            ]);
            LogisticsRecord::create([
                'lst_id' => $logistics['id'],
                'type' => 2,
                'user_name' => $logistics['courier_name'],
                'user_phone' => $logistics['courier_phone'],
                'content' => '已完成配送',
                'create_time' => time(),
            ]);
            Logistics::commit();
        } catch (\Exception $e) {
            Logistics::rollback();
            return ['code'=>0, 'msg'=>$e->getMessage()];
        }
        //调用接口通知商超平台
        $url = env('project.shop_notify_domain').'/api/goods/take/'.$logistics['order_id'];
        curl_post($url,[],['order_sn'=>$logistics['order_sn'],'logistics_code'=>$params['take_code']]);
        return ['code'=>1, 'msg'=>'操作成功'];
    }

    /*
     * 取消订单
     * @param $params
     * @return array
     */
    public static function cancel($params):array {
        //获取物流信息
        $logistics = Logistics::where('order_id', $params['order_id'])->where('order_sn',$params['order_sn'])->find();
        if (!$logistics) return ['code'=>0, 'msg'=>'物流信息不存在'];
        //判断物流信息状态
        switch ($logistics['status']) {
            case 1:
                return ['code'=>0, 'msg'=>'该商品正在配送中'];
            case 2:
                return ['code'=>0, 'msg'=>'该商品已完成配送'];
        }
        //更改物流信息状态
        Logistics::startTrans();
        try {
            Logistics::where('id', $logistics['id'])->update([
                'status' => 3,
                'update_time' => time(),
                'qx_time' => time(),
            ]);
            LogisticsRecord::create([
                'lst_id' => $logistics['id'],
                'type' => 1,
                'user_name' => $logistics['user_name'],
                'user_phone' => $logistics['user_phone'],
                'content' => '已取消订单',
                'create_time' => time(),
            ]);
            Logistics::commit();
            return ['code'=>1, 'msg'=>'操作成功'];
        } catch (\Exception $e) {
            Logistics::rollback();
            return ['code'=>0, 'msg'=>$e->getMessage()];
        }
    }

    public static function getCoutier($code):bool {
        //获取队长用户信息
        $captain = Courier::field('id,company_id,nickname,mobile')->where("CONCAT_WS(',',province,city,area,street,village,brigade) = '". $code ."'")->where('is_captain',1)->find();
        if(!$captain) return false;
        //获取配送员信息
        $courier = Company::field('company_name,user_id,master_name,master_phone')->where('id',$captain['company_id'])->find();
        if(!$courier) return false;
        return true;
    }

}