laravel implementation order list

Keywords: PHP Laravel

First, you need to create an order table

Create the database migration file when creating the model

php artisan make:model Order -m

Perfect database fields

public function up()
    {
        Schema::create('orders', function (Blueprint $table) {
            $table->id();
            $table->integer('user_id')->comment('User placing the order');
            $table->string('order_on')->comment('Order No');
            $table->decimal('amount')->comment('Total amount');
            $table->tinyInteger('status')->default(1)->comment('Order status 1 order 2 payment 3 shipment 4 receipt');
            $table->integer('address_id')->comment('Receiving address');
            $table->string('express_type')->comment('Express type SF YT YD');
            $table->string('express_no')->comment('courier number');
            $table->timestamp('pay_time')->nullable()->comment('Payment time');
            $table->string('pay_type')->nullable()->comment('Payment type:Alipay WeChat');
            $table->string('trade_no')->nullable()->comment('Payment No');
            $table->timestamps();
        });
    }

Since an order may contain multiple items, a slave table is required

Create an order detail model and create a database migration file

php artisan make:model OrderDetails -m

Perfect database fields

public function up()
    {
        Schema::create('order_details', function (Blueprint $table) {
            $table->id();
            $table->integer('order_id')->comment('Order');
            $table->integer('goods_id')->comment('commodity');
            //Why do you want to set the order price? It should be based on the price when the user pays, not the price of the goods
            $table->integer('price')->comment('prices for goods');
            $table->integer('num')->comment('Quantity of goods');
            $table->timestamps();
        });
    }

Now you can create the controller for the order
In order controller

/*
     * Order list
     */
    public function index(Request $request)
    {
        //query criteria
        //order number
        $order_no = $request->input('order_no');
        //Payment No
        $trade_no = $request->input('trade_no');
        //Order status
        $status = $request->input('status');
        $orders = Order::when($order_no,function ($query) use ($order_no){
            $query->where('order_no',$order_no);
        })->when($trade_no,function ($query) use ($trade_no){
            $query->where('trade_no',$trade_no);
        })->when($status,function ($query) use ($status){
            $query->where('status',$status);
        })->paginate();
        return $this->response->paginator($orders, new OrderTransformer());
    }

Then create the Transformer file of the order

Data fields to be returned

public function transform(Order $order)
    {
        return [
            'id' => $order->id,
            'order_no' => $order->order_on,
            'user_id' => $order->user_id,
            'amount' => $order->amount,
            'status' => $order->status,
            'address_id' => $order->address_id,
            'express_type' => $order->express_type,
            'express_no' => $order->express_no,
            'pay_time' => $order->pay_time,
            'pay_type' => $order->pay_type,
            'trade_no' => $order->trade_no,
            'created_at' => $order->created_at,
            'updated_at' => $order->updated_at,
        ];
    }

Then the data can be returned normally. However, do you feel that the data is a little simple?
For example, it's impossible to go again_ Id write the query again?

Therefore, laravel's dingoApi provides methods that can return additional data, which are encapsulated by laravel dingoApi
Define a protected method in the Transformer file

//This method provides additional data to return
protected $availableIncludes = ['user', 'orderDetails'];

Then, query corresponding to the non mandatory parameter in the route
Key: include value: defines the value in the availableIncludes data
For example, I want to return user data in an extra
Then include:user

Returns multiple additional data, separated by
If you want to go to the next level to obtain data, use the. Number
for example

Of course, you need to obtain additional data. It is not enough to define only $availableIncludes. You also need to define the corresponding association
For example:
Note: it is also a method defined in Transformer

 /*
     * Additional user data
     */
    public function includeUser(Order $order)
    {
        return $this->item($order->user, new UserTransformer());
    }

    /*
     * Additional order data
     */
    public function includeorderDetails(Order $order)
    {
        return $this->collection($order->orderDetails, new OrderDetailsTransformer());
    }

Among them, including user (order $order) will be decomposed into the data obtained from the model association defined in the current model by default

includeUser(Order $order) means to obtain the User association from the order model. Let's take a look at the association in the order model

Sure enough, the order model contains the user association

The two associations I define are

/**
     * User
     */
    public function user()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
    /*
     * Order details owned by the order
     */
    public function orderDetails(){
        return $this->hasMany(OrderDetails::class,'order_id','id');
    }

In this way, you can use the Transformer to return additional data. However, I mentioned above that you can also obtain deeper data by using the. Sign,
For example, orderDetails.goods means to find the corresponding goods association in includeorderderdetails in OrderTransformer
Let's see if it's relevant
Sure enough

It can be found that there are good

  /*
     * Additional goods
     */
    public function includeGoods(OrderDetails $orderDetails)
    {
        return $this->item($orderDetails->goods, new GoodTransformer());
    }

So, you can get the data,
In fact, it is not recommended to obtain more layers of data. Generally, two times is enough. More will cause confusion in my thinking

Add: if you need to use dingo API,

It needs to be introduced. Like myself, it needs to be introduced into the controller,
First, create a BaseController controller,

It can only be used by introducing Helpers,
After importing, you can directly inherit BaseController and use it

Posted by sabatier on Sat, 20 Nov 2021 00:01:59 -0800