为了账号安全,请及时绑定邮箱和手机立即绑定

Integrity constraint violation: 1048,明明已经赋值了-商城构建全栈应用10-14 测试订单接口

/ 猿问

Integrity constraint violation: 1048,明明已经赋值了-商城构建全栈应用10-14 测试订单接口

Jenky奇 2019-12-03 13:30:49

http://img1.sycdn.imooc.com/5de5f0dc0001a32d16560616.jpghttp://img1.sycdn.imooc.com/5de5f214000100c706541150.jpg

 http://img4.sycdn.imooc.com/5de5f22900011f9e07050801.jpghttp://img1.sycdn.imooc.com/5de5f236000163dc07210659.jpghttp://img3.sycdn.imooc.com/5de5f245000136ef07461015.jpghttp://img1.sycdn.imooc.com/5de5f25200019aca07530433.jpg

<?php

namespace app\api\service;

use app\api\model\OrderProduct;
use app\api\model\Product;
use app\api\model\UserAddress;
use app\lib\exception\OrderException;
use app\lib\exception\UserException;
use think\Exception;

class Order
{
    // 订单的商品列表,客户端传递来的下单商品参数--二维数组
    protected $oProducts;

    // 根据product_id从数据库中查询出的真实商品信息--库存量
    protected $products;

    protected $uid;

    // 下单方法,参数$uid--用户,$oProducts
    public function place($uid, $oProducts)
    {
        // 将传进来的$uid和$oProducts赋值给成员变量$uid和$oProducts
        $this->uid = $uid;
        $this->oProducts = $oProducts;

        // 从数据库中获取$products的信息,调用方法getProductsByOrder
        $this->products = $this->getProductsByOrder($oProducts);

        // 获取getOrderStatus方法的返回结果
        $status = $this->getOrderStatus();
        // 查看库存量是否通过,未通过则:
        if (!$status['pass']) {
            //在$status数组中增加订单编号为-1,表示订单创建失败值,作为标记
            $status['order_id'] = -1;
            //返回结果到客户端,
            return $status;
        }

        // 库存量通过,则创建订单.第一步,创建订单快照
        $orderSnap = $this->snapOrder($status);
        $order = $this->createOrder($orderSnap);
        $order['pass'] = true;
        return $order;
    }

    // 10-12
    // 第二步,创建订单
    private function createOrder($snap)
    {
        try {
            // 订单号
            $orderNo = $this->makeOrderNo();
            // 实例化order模型
            $order = new \app\api\model\Order();
            // 数据库的order表中插入数据
            $order->user_id = $this->uid;
            $order->order_no = $orderNo;
            $order->total_price = $snap['orderPrice'];
            $order->total_count = $snap['totalCount'];
            $order->snap_img = $snap['snapImg'];
            $order->snap_name = $snap['snapNme'];
            $order->snap_address = $snap['snapAddress'];
            $order->snap_items = json_encode($snap['pStatus']);

            $order->save();

            // order表的id 插入 到order_product的order_id赋值
            // 获取order表的id和create_time
            $orderID = $order->id;
            $create_time = $order->create_time;
            // 为订单中的每一个商品添加$orderID
            // &引用符号,才能够在数组中增加字段
            foreach ($this->oProducts as &$p) {
                $p['order_id'] = $orderID;
            }

            //调用模型orderproduct,将数据保存到数据库order_product表
            $orderProduct = new OrderProduct();
            // 保存数组需要调用saveAll方法
            $orderProduct->saveAll($this->oProducts);
            return [
                'order_no' => $orderNo,
                'order_id' => $orderID,
                'create_time' => $create_time
            ];
        } catch (Exception $ex) {
            throw $ex;
        }
    }

    // 生成订单号
    public static function makeOrderNo()
    {
        $yCode = array('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J');
        $orderSn =
            $yCode[intval(date('Y')) - 2019] . strtoupper(dechex(date('m'))) . date(
                'd') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf(
                '%02d', rand(0, 99));
        return $orderSn;
    }

    // 10-11
    // 生成订单快照
    private function snapOrder($status)
    {
        //快照信息的关联数组
        $snap = [
            //商品总价
            'orderPrice' => 0,
            //所有商品的数量和
            'totalCount' => 0,
            //单类商品的详细信息
            'pStatus' => [],
            //快照地址,快照商品名,快照商品图
            'snapAddress' => null,
            //订单中第一个商品的名字和图片作为快照
            'snapName' => '',
            'snapImg' => ''
        ];

        $snap['orderPrice'] = $status['orderPrice'];
        $snap['totalCount'] = $status['totalCount'];
        $snap['pStatus'] = $status['pStatusArray'];
        //将$userAddress数组序列化为json字符串,方便存入数据库中,但不太好.
        $snap['snapAddress'] = json_encode($this->getUserAddress());
        $snap['snapName'] = $this->products[0]['name'];
        $snap['snapImg'] = $this->products[0]['main_img_url'];

        if (count($this->products) > 1) {
            $snap['snapName'] .= '等';
        }

//        print_r($snap);
    }

    // 获取快照地址
    private function getUserAddress()
    {
        //获取$userAddress对象
        $userAddress = UserAddress::where('user_id', '=', $this->uid)->find();
        if (!$userAddress) {
            throw new UserException([
                'msg' => '用户收货地址不存在,下单失败',
                'errorCode' => 60001
            ]);
        }
        //返回$userAddress数组
        return $userAddress->toArray();
    }

    // 10-9 下单接口业务模型二
    // 定义方法:获取订单状态.对比$oProducts和$products,检验库存量
    // 此处不需要传递参数$oProducts和$products,是因为本类中已经定了赋值好了.
    // 定义订单状态相关属性,用于返回结果
    //      pass--库存量检测是否通过,默认值设为true
    //      orderPrice--所有商品价格总和,默认值设为0
    //      pStatusArray--数组,通过order的product_id获取并保存订单中所有商品的详细信息
    //                  用于历史订单,默认值设为空数组

    //获取订单状态,返回值为数组,包含库存量是否充足,所有商品总价,和所有订单商品的详细信息.
    private function getOrderStatus()
    {
        $status = [
            'pass' => true,
            'orderPrice' => 0,
            'totalCount' => 0,
            'pStatusArray' => []
        ];

        // 使用循环对比进行库存量检测
        foreach ($this->oProducts as $oProduct) {
            $pStatus = $this->getProductStatus(
                $oProduct['product_id'], $oProduct['count'], $this->products
            );
            if (!$pStatus['haveStock']) {
                $status['pass'] = false;
            }
            $status['orderPrice'] += $pStatus['totalPrice'];
            $status['totalCount'] += $pStatus['count'];
            array_push($status['pStatusArray'], $pStatus);
        }
        return $status;
    }




    // 定义方法getProductStatus
    // 根据$oPIDs中的product_id获取$products数组中对应的商品库存量
    // $oPIDs数组中只有product_id
    // 定义$pStatus的数据结构
    //      $pStatus的作用,将本次订单信息保存至历史订单
    // $pIndex指定product_id在$products中id对应数组的下标序号
    // totalPrice--订单中某个商品的总价格
    private function getProductStatus($oPIDs, $oCount, $products)
    {
        $pIndex = -1;
        $pStatus = [
            'id' => null,
            'haveStock' => false,
            //订单中某个商品的数量
            'count' => 0,
            'name' => '',
            'totalPrice' => 0
        ];

        //使用循环找出$pIndex
        for ($i = 0; $i < count($products); $i++) {
            if ($oPIDs == $products[$i]['id']) {
                $pIndex = $i;
            }
        }

        if ($pIndex == -1) {
            //以防用户下单的商品客户端传递的productid有可能根本不存在,在服务器中已经下架了或丢失了,即$pIndex = -1,需要抛出异常
            throw new OrderException([
                'msg' => 'id为' . $oPIDs . '的商品不存在,订单创建失败'
            ]);
        } else {
            $products = $products[$pIndex];
            $pStatus['id'] = $products['id'];
            $pStatus['count'] = $oCount;
            $pStatus['name'] = $products['name'];
            $pStatus['totalPrice'] = $products['price'] * $oCount;
            if ($products['stock'] - $oCount >= 0) {
                $pStatus['haveStock'] = true;
            }
        }
        return $pStatus;
    }




    // 根据订单信息$oProducts查找真实的商品信息$products
    private function getProductsByOrder($oProducts)
    {
        // 通过循环将product_id读取出来并存放在$oPIDs数组中,$oPIDs是一个只有product_id的以为数组.
        $oPIDs = [];
        foreach ($oProducts as $item) {
            array_push($oPIDs, $item['product_id']);
        }
        // 通过新构造的数组$oPIDs,调用Product模型的all方法到数据库中进行硬查询
        //      并使用->visible方法获取指定部分数据
        //   之前在全局配置中数组返回形式是collection数据集,
        //   此处使用数据集的toArray方法将数据集转化为数组形式(方便与$oProducts数组作对比)
        // 查询结构$products是一个二维数组
        $products = Product::all($oPIDs)
            ->visible(['id', 'price', 'stock', 'name', 'main_img_url'])
            ->toArray();
        return $products;
    }
}


查看完整描述

目前暂无任何回答

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信