Litestoreorder.php 13.6 KB
<?php

namespace addons\litestore\model;

use think\Model;
use think\Db;

class Litestoreorder extends Model
{
    // 表名
    protected $name = 'litestore_order';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';

    // 追加属性
    protected $append = [
        'pay_status_text',
        'pay_time_text',
        'freight_status_text',
        'freight_time_text',
        'receipt_status_text',
        'receipt_time_text',
        'order_status_text',
        'creattime_text',
    ];

    public function cancel($user_id,$order_id){
        if ($this['pay_status'] === '20') {
            $this->error = '已付款订单不可取消';
            return false;
        }
        $goods = $this['goods'];
        $this->backGoodsStock($goods);

        $order = self::get([
            'id' => $order_id,
            'user_id' => $user_id,
            'order_status' => ['<>', '20']
        ]);

        return $order->save([
            'order_status' => '20'
        ]);
    }
    private function backGoodsStock(&$goodsList)
    {
        $goodsSpecSave = [];
        foreach ($goodsList as $goods) {
            // 下单减库存
            if ($goods['deduct_stock_type'] === '10') {
                $goodsSpecSave[] = [
                    'goods_spec_id' => $goods['goods_spec_id'],
                    'stock_num' => ['inc', $goods['total_num']]
                ];
            }
        }
        if(!empty($goodsSpecSave)){
        // 更新商品规格库存
            return (new Litestoregoodsspec)->isUpdate()->saveAll($goodsSpecSave);
        }
        return true;
    }

    public function finish($user_id,$order_id){
        if (!$order = self::get([
            'id' => $order_id,
            'user_id' => $user_id,
            'order_status' => ['<>', '20']
        ])) {
            throw new BaseException(['msg' => '订单不存在']);
        }
        if ($order['freight_status'] === '10' || $order['receipt_status'] === '20') {
            $order->error = '该订单不合法';
            return false;
        }
        return $order->save([
            'receipt_status' => '20',
            'receipt_time' => time(),
            'order_status' => '30'
        ]);
    }

    public function checkGoodsStatusFromOrder($goodsList){
        foreach ($goodsList as $goods) {
            //商品是否下架
            if ($goods['goods']['goods_status'] !== '10') {
                $this->setError('很抱歉,商品 [' . $goods['goods_name'] . '] 已下架');
                return false;
            }
            //付款减库存
            if ($goods['deduct_stock_type'] === '20' && $goods['spec']['stock_num'] < 1) {
                $this->setError('很抱歉,商品 [' . $goods['goods_name'] . '] 库存不足');
                return false;
            }
        }
        return true;
    }

    public function getList($user_id){
        return $this->with(['goods'])
            ->where('user_id', '=', $user_id)
            ->where('order_status', '<>', '20')
            ->order(['createtime' => 'desc'])->limit(50)
            ->select();
    }

    public function getOrderDetail($order_id, $user_id){
        if (!$order = self::get([
            'id' => $order_id,
            'user_id' => $user_id,
            'order_status' => ['<>', '20']
        ], ['goods'=>['spec','goods']])) {
            throw new BaseException(['msg' => '订单不存在']);
        }
        $goodsList = [];
        foreach ($order['goods'] as $index => $item) {
            $item['image'] = cdnurl(explode(",",$item['images'])[0], true);
            $item['sku_image'] = $item['spec']['spec_image']=='' ? '' : cdnurl($item['spec']['spec_image'], true);
            $goodsList[] = $item;
        }
        $order['goods'] = $goodsList;
        return $order;
    }

    public function payDetail($order_no){
        return self::get(['order_no' => $order_no, 'pay_status' => 10], ['goods']);
    }

    public function getCart($user_id){
        $model = new CacheCart($user_id);
        return $model->getList($user_id);
    }
    
    public function CarclearAll($user_id){
        $Card = new CacheCart($user_id);
        $Card->clearAll();
    }

    public function getBuyNow($user_id, $goods_id, $goods_num, $goods_sku_id)
    {
        // 商品信息
        $goods = Wxlitestoregoods::detail($goods_id);
        return $goods;
        $goods['show_error'] = 0;
        // 判断商品是否下架
        if ($goods['goods_status'] !== '10') {
            $goods['show_error'] = 1;
            $goods['show_error_text'] = '已下架';
            $this->setError('很抱歉,商品信息不存在或已下架');
        }
        // 商品sku信息
        $goods['goods_sku'] = $goods->getGoodsSku($goods_sku_id);
        // 判断商品库存
        if ($goods_num > $goods['goods_sku']['stock_num']) {
            $goods['show_error'] = 2;
            $goods['show_error_text'] = '库存不足';
            $this->setError('很抱歉,商品库存不足');
        }
        // 商品单价
        $goods['goods_price'] = $goods['goods_sku']['goods_price'];
        // 商品总价
        $goods['total_num'] = $goods_num;
        $goods['total_price'] = $totalPrice = bcmul($goods['goods_price'], $goods_num, 2);
        // 商品总重量
        $goods_total_weight = bcmul($goods['goods_sku']['goods_weight'], $goods_num, 2);
//        // 当前用户收货城市id
//        $defaultcity = Litestoreadress::getdefault($user_id);
//        $cityId = $defaultcity ? $defaultcity['city_id'] : null;
//        // 是否存在收货地址
//        $exist_address = $defaultcity;
//        // 验证用户收货地址是否存在运费规则中
//        if (!$intraRegion = $goods['freight']->checkAddress($cityId)) {
//            $exist_address && $this->setError('很抱歉,您的收货地址不在配送范围内');
//        }
//        // 计算配送费用
//        $expressPrice = $intraRegion ?
//            $goods['freight']->calcTotalFee($goods_num, $goods_total_weight, $cityId) : 0;
        return [
            'goods_list' => [$goods],               // 商品详情
            'order_total_num' => $goods_num,        // 商品总数量
            'order_total_price' => $totalPrice,    // 商品总金额 (不含运费)
            'order_pay_price' => $totalPrice,  // 实际支付金额
//            'order_pay_price' => bcadd($totalPrice, $expressPrice, 2),  // 实际支付金额
//            'address' => $defaultcity,  // 默认地址
//            'exist_address' => $exist_address,  // 是否存在收货地址
//            'express_price' => $expressPrice,    // 配送费用
//            'intra_region' => $intraRegion,    // 当前用户收货城市是否存在配送规则中
            'has_error' => $this->hasError(),
            'error_msg' => $this->getError(),
        ];
    }

    public function order_add($user_id, $order){
//        if (empty($order['address'])) {
//            $this->error = '请先选择收货地址';
//            return false;
//        }
        Db::startTrans();
        // 记录订单信息
        $this->save([
            'user_id' => $user_id,
            'order_no' => $this->orderNo(),
            'total_price' => $order['order_total_price'],
            'pay_price' => $order['order_pay_price'],
//            'express_price' => $order['express_price'],
        ]);
        // 订单商品列表
        $goodsList = [];
        // 更新商品库存 (下单减库存)
        $deductStockData = [];
        foreach ($order['goods_list'] as $goods) {
            /* @var Goods $goods */
            $goodsList[] = [
                'user_id' => $user_id,
                'goods_id' => $goods['goods_id'],
                'goods_name' => $goods['goods_name'],
                'images' => $goods['images'],
                'deduct_stock_type' => $goods['deduct_stock_type'],
                'spec_type' => $goods['spec_type'],
                'spec_sku_id' => $goods['goods_sku']['spec_sku_id'],
                'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
                'goods_attr' => $goods['goods_sku']['goods_attr'],
                'content' => $goods['content'],
                'goods_no' => $goods['goods_sku']['goods_no'],
                'goods_price' => $goods['goods_sku']['goods_price'],
                'line_price' => $goods['goods_sku']['line_price'],
                'goods_weight' => $goods['goods_sku']['goods_weight'],
                'total_num' => $goods['total_num'],
                'total_price' => $goods['total_price'],
            ];
            // 下单减库存
            $goods['deduct_stock_type'] === '10' && $deductStockData[] = [
                'goods_spec_id' => $goods['goods_sku']['goods_spec_id'],
                'stock_num' => ['dec', $goods['total_num']]
            ];
        }
        // 保存订单商品信息
        $this->goods()->saveAll($goodsList);
        // 更新商品库存
        !empty($deductStockData) && (new Litestoregoodsspec)->isUpdate()->saveAll($deductStockData);
//        // 记录收货地址
//        $this->address()->save([
//            'user_id' => $user_id,
//            'name' => $order['address']['name'],
//            'phone' => $order['address']['phone'],
//            'province_id' => $order['address']['province_id'],
//            'city_id' => $order['address']['city_id'],
//            'region_id' => $order['address']['region_id'],
//            'detail' => $order['address']['detail'],
//        ]);
        Db::commit();
        return true;
    }
    
    public function getPayStatusList()
    {
        return ['10' => __('Pay_status 10'),'20' => __('Pay_status 20')];
    }     

    public function getFreightStatusList()
    {
        return ['10' => __('Freight_status 10'),'20' => __('Freight_status 20')];
    }     

    public function getReceiptStatusList()
    {
        return ['10' => __('Receipt_status 10'),'20' => __('Receipt_status 20')];
    }     

    public function getOrderStatusList()
    {
        return ['10' => __('Order_status 10'),'20' => __('Order_status 20'),'30' => __('Order_status 30')];
    }     


    public function getPayStatusTextAttr($value, $data)
    {        
        $value = $value ? $value : (isset($data['pay_status']) ? $data['pay_status'] : '');
        $list = $this->getPayStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getPayTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['pay_time']) ? $data['pay_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getFreightStatusTextAttr($value, $data)
    {        
        $value = $value ? $value : (isset($data['freight_status']) ? $data['freight_status'] : '');
        $list = $this->getFreightStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getFreightTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['freight_time']) ? $data['freight_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getReceiptStatusTextAttr($value, $data)
    {        
        $value = $value ? $value : (isset($data['receipt_status']) ? $data['receipt_status'] : '');
        $list = $this->getReceiptStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }


    public function getReceiptTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['receipt_time']) ? $data['receipt_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getOrderStatusTextAttr($value, $data)
    {        
        $value = $value ? $value : (isset($data['order_status']) ? $data['order_status'] : '');
        $list = $this->getOrderStatusList();
        return isset($list[$value]) ? $list[$value] : '';
    }

    public function getCreattimeTextAttr($value, $data)
    {        
        $value = $value ? $value : (isset($data['createtime']) ? $data['createtime'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;;
    }

    protected function setPayTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setFreightTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setReceiptTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    public function goods()
    {
        return $this->hasMany('Litestoreordergoods','order_id', 'id');
    }

    public function address()
    {
        return $this->hasOne('Litestoreorderaddress', 'order_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    private function setError($error)
    {
        empty($this->error) && $this->error = $error;
    }

    protected function orderNo()
    {
        return date('Ymd') . substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
    }

    public function hasError()
    {
        return !empty($this->error);
    }

    public function updatePayStatus($transaction_id)
    {
        Db::startTrans();
        // 更新商品库存、销量
        $GoodsModel = new Wxlitestoregoods;
        $GoodsModel->updateStockSales($this['goods']);
        // 更新订单状态
        $this->save([
            'pay_status' => '20',
            'pay_time' => time(),
            'transaction_id' => $transaction_id,
        ]);
        Db::commit();
        return true;
    }
}