StoreExpress.php 14.1 KB
<?php

namespace app\admin\controller\groupon\order;

use addons\groupon\library\Export;
use addons\groupon\model\Config as ModelConfig;
use app\admin\model\groupon\order\OrderStoreExpress;
use app\admin\model\groupon\order\OrderExpressLog;
use think\Db;
use think\Config;
use app\common\controller\Backend;
use app\admin\controller\groupon\Base;
use addons\groupon\library\traits\export\ExportOrder;

/**
 * 门店包裹
 *
 * @icon fa fa-circle-o
 */
class StoreExpress extends Base
{
    use ExportOrder;

    protected $noNeedRight = ['getType', 'getExpress'];

    /**
     * Order模型对象
     * @var \app\admin\model\groupon\order\Order
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();

        // 手动加载语言包
        $this->loadlang('groupon/order/order');
        $this->loadlang('groupon/order/order_item');
        $this->loadlang('groupon/goods/goods');

        $this->model = new \app\admin\model\groupon\order\OrderStoreExpress;
        $this->orderModel = new \app\admin\model\groupon\order\Order;
        $this->orderItemModel = new \app\admin\model\groupon\order\OrderItem;
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */


    /**
     * 查看
     */
    public function index()
    {
        //当前是否为关联查询
        $this->relationSearch = true;
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage,则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }

            $nobuildfields = ['store_name'];
            list($where, $sort, $order, $offset, $limit) = $this->custombuildparams(null, $nobuildfields);

            $total = $this->buildSearch()
                ->where($where)
                ->order($sort, $order)
                ->count();

            $list = $this->buildSearch()
                ->where($where)
                ->with(['store'])
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();

            // foreach ($list as $row) {
            //     $row->visible(['id','type','order_sn','user','item','user_id','phone','consignee','province_name','city_name','area_name','address','status','memo','remark','total_amount','total_fee','createtime']);
            // }
            
            $result = array("total" => $total, "rows" => $list);

            return $this->success('操作成功', null, $result);
        }
        return $this->view->fetch();
    }


    public function detail($id)
    {
        if ($this->request->isAjax()) {
            $row = $this->model->with(['store'])->where('id', $id)->find();
            if (!$row) {
                $this->error(__('No Results were found'));
            }
            $row = $row->toArray();
            $row['log'] = OrderExpressLog::where('order_express_id', $id)->where('store_id', $row['store_id'])->order('id', 'desc')->select();

            $items = $this->orderItemModel->where('store_express_id', $id)->select();

            $goods = [];
            foreach ($items as $key => $item) {
                $goodsKey = $item['goods_id'] . '-' . $item['goods_sku_price_id'];
                if (isset($goods[$goodsKey])){
                    $goods[$goodsKey]['goods_num'] = $goods[$goodsKey]['goods_num'] + $item['goods_num'];
                } else {
                    $goods[$goodsKey] = $item;
                }
            }

            $orders = $this->orderModel->with(['user', 'store', 'item' => function ($query) use ($id) {
                $query->where('store_express_id', $id);
            }])->whereExists(function ($query) use ($id) {
                $itemTableName = (new \app\admin\model\groupon\order\OrderItem())->getQuery()->getTable();
                $orderTableName = (new \app\admin\model\groupon\order\Order())->getQuery()->getTable();

                $query = $query->table($itemTableName)->where($itemTableName . '.order_id=' . $orderTableName . '.id');

                $query = $query->where('store_express_id', $id);

                return $query;
            })->select();

            return $this->success('获取成功', null, [
                'row' => $row,
                'orders' => $orders,
                'goods' => array_values($goods),
                'item_ids' => array_column($items, 'id')
            ]);
        }

        $this->assignconfig('id', $id);
        return $this->view->fetch();
    }



    public function export($id) {
        $orderStoreExpress = $this->model->with(['store'])->where('id', $id)->find();

        if (!$orderStoreExpress) {
            $this->error(__('No Results were found'));
        }
        
        $this->exportOutput($orderStoreExpress);
    }



    /**
     * 发货
     *
     * @param [type] $store_id
     * @param integer $express_id
     */
    public function send($store_id, $express_id = 0) {
        if ($this->request->isAjax()) {
            $data = $this->request->post();
            
            $item_ids = $data['item_ids'] ?? [];
            $item_ids = is_array($item_ids) ? $item_ids : explode(',', $item_ids);

            if (!$item_ids) {
                $this->error('请选择要发货的商品');
            }

            // 查询所有要备货的订单
            $items = $this->getSendOrderItem($store_id, $item_ids, $express_id);

            if (!$items) {
                $this->error('没有可发货商品');
            }

            // 编辑包裹
            $orderStoreExpress = null;
            $need_subscribe = true;
            if ($express_id) {
                // 修改包裹
                $orderStoreExpress = OrderStoreExpress::where('id', $express_id)->find();
                if (!$orderStoreExpress) {
                    $this->error('包裹不存在');
                }
            }

            $orderExpress = Db::transaction(function () use ($store_id, $items, $orderStoreExpress) {
                $item_ids = array_column($items, 'id');

                if (!$orderStoreExpress) {
                    // 添加包裹
                    $orderStoreExpress = new OrderStoreExpress();
                    $orderStoreExpress->store_id = $store_id;
                    $orderStoreExpress->code = OrderStoreExpress::getCode($store_id);
                } else {
                    // 查询包裹老的商品,并且不在这次所选择之中,改为未发货
                    \app\admin\model\groupon\order\OrderItem::where('id', 'not in', $item_ids)
                        ->where('store_express_id', $orderStoreExpress->id)
                        ->update([
                            'store_express_id' => 0,
                            'dispatch_status' => \app\admin\model\groupon\order\OrderItem::DISPATCH_STATUS_NOSEND
                        ]);
                }

                $orderStoreExpress->save();

                foreach ($items as $key => $item) {
                    $order = $item['order'];
                    $order->sendItemToStore($order, $item, [
                        "store_express_id" => $orderStoreExpress->id,
                        "oper" => $this->auth->getUserInfo(),
                        "oper_type" => 'admin',
                    ]);
                }

                // 查询已经没有商品的包裹,并且删除
                OrderStoreExpress::whereNotExists(function ($query) use ($order, $store_id) {
                    $order_table_name = (new OrderStoreExpress())->getQuery()->getTable();
                    $table_name = (new \app\admin\model\groupon\order\OrderItem())->getQuery()->getTable();
                    $query->table($table_name)->where($table_name . '.store_express_id=' . $order_table_name . '.id')
                        ->where('store_id', $store_id);
                })->where('store_id', $store_id)->delete();

                return $orderStoreExpress;
            });

            return $this->success('发货成功' . (isset($sub_msg) ? ': ' . $sub_msg : ''), null);
        }

        return $this->view->fetch();
    }



    /**
     * 修改物流单号
     *
     * @param [type] $express_id
     * @return void
     */
    public function setExpress($express_id) {
        $express_name = $this->request->post('express_name', '');
        $express_code = $this->request->post('express_code', '');
        $express_no = $this->request->post('express_no', '');

        if (!$express_name || !$express_code || !$express_no) {
            $this->error('请填写完整发货信息');
        }

        $need_subscribe = true;
        $orderStoreExpress = OrderStoreExpress::where('id', $express_id)->find();
        if (!$orderStoreExpress) {
            $this->error('包裹不存在');
        }

        if ($orderStoreExpress->express_no == $express_no && $orderStoreExpress->express_code == $express_code) {
            // 没有编辑快递信息,不需要重新订阅快递
            $need_subscribe = false;
        }

        // 修改快递信息
        $orderStoreExpress->express_name = $express_name;
        $orderStoreExpress->express_code = $express_code;
        $orderStoreExpress->express_no = $express_no;
        $orderStoreExpress->dispatch_status = OrderStoreExpress::DISPATCH_STATUS_SENDED;
        $orderStoreExpress->save();

        // 将快递信息上报快递 api
        if ($need_subscribe) {
            try {
                $expressLib = new \addons\groupon\library\Express();
                $expressLib->subscribe([
                    'express_code' => $express_code,
                    'express_no' => $express_no,
                    'order_code' => $orderStoreExpress->code
                ], $orderStoreExpress, null);
            } catch (\Exception $e) {
                $sub_msg = $e->getMessage();
            }
        }

        return $this->success('修改成功', null);
    }



    /**
     * 获取物流快递信息
     */
    public function getExpress($express_id = 0)
    {
        $type = $this->request->get('type');

        // 获取包裹
        $orderStoreExpress = OrderStoreExpress::where('id', $express_id)->find();
        if (!$orderStoreExpress) {
            return $this->error('包裹不存在');
        }

        $expressLib = new \addons\groupon\library\Express();

        try {
            if ($type == 'subscribe') {
                // 重新订阅
                $expressLib->subscribe([
                    'express_code' => $orderStoreExpress['express_code'],
                    'express_no' => $orderStoreExpress['express_no'],
                    'order_code' => $orderStoreExpress['code']
                ], $orderStoreExpress, null);
            } else {
                // 手动查询
                $result = $expressLib->search([
                    'express_code' => $orderStoreExpress['express_code'],
                    'express_no' => $orderStoreExpress['express_no'],
                    'order_code' => $orderStoreExpress['code']
                ], $orderStoreExpress, null);

                // 差异更新物流信息
                $expressLib->checkAndAddTraces($orderStoreExpress, $result);
            }

        } catch (\Exception $e) {
            return $this->error(($type == 'subscribe' ? '订阅失败' : '刷新失败') . $e->getMessage());
        }

        return $this->success(($type == 'subscribe' ? '订阅成功' : '刷新成功'), null);
    }


    // 构建查询条件
    private function buildSearch()
    {
        $filter = $this->request->get("filter", '');
        $filter = (array)json_decode($filter, true);
        $filter = $filter ? $filter : [];

        $store_name = isset($filter['store_name']) ? $filter['store_name'] : '';

        $name = $this->model->getQuery()->getTable();
        $tableName = $name . '.';

        $storeExpress = $this->model;

        if ($store_name) {
            $storeExpress = $storeExpress->whereExists(function ($query) use ($store_name, $tableName) {
                $storeTableName = (new \app\admin\model\groupon\store\Store())->getQuery()->getTable();

                $query = $query->table($storeTableName)->where($storeTableName . '.id=' . $tableName . 'store_id');

                if ($store_name) {
                    $query = $query->where('name', 'like', "%{$store_name}%");
                }

                return $query;
            });
        }

        return $storeExpress;
    }



    private function getSendOrderItem($store_id, $item_ids, $express_id)
    {
        $name = (new \app\admin\model\groupon\order\OrderItem)->getQuery()->getTable();
        $tableName = $name . '.';

        $dispatchWhere = [
            \app\admin\model\groupon\order\OrderItem::DISPATCH_STATUS_NOSEND,
        ];
        if ($express_id) {
            // 如果是编辑,要把已备货的也查出来
            $dispatchWhere[] = \app\admin\model\groupon\order\OrderItem::DISPATCH_STATUS_READY;
        }

        // 查询 orderItem
        $items = \app\admin\model\groupon\order\OrderItem::with('order')
            ->where('id', 'in', $item_ids)
            ->where('store_id', $store_id)
            ->where('dispatch_type', 'selfetch')
            ->where('dispatch_status', 'in', $dispatchWhere)
            ->where('refund_status', 'not in', [\app\admin\model\groupon\order\OrderItem::REFUND_STATUS_OK, \app\admin\model\groupon\order\OrderItem::REFUND_STATUS_FINISH])
            ->whereExists(function ($query) use ($tableName) {
                $orderTableName = (new \app\admin\model\groupon\order\Order())->getQuery()->getTable();

                $query = $query->table($orderTableName)->where($orderTableName . '.id=' . $tableName . 'order_id');

                $query = $query->where('status', '>', 0);

                return $query;
            })
            ->select();

        return $items;
    }
}