roketin / stellar-connect

Roketin Stellar API 客户端

v0.0.15 2019-08-15 09:48 UTC

This package is auto-updated.

Last update: 2024-09-15 21:56:51 UTC


README

Latest Version License Total Downloads

RClient 是标准客户端应用程序,用于加速连接和集成 Roketin Engine API 的基本功能到客户的网站。

API 文档

Roketin API 的文档可以在这里找到。

安装

Laravel 5

    "require": {
        "laravel/framework": "5.0.*",
        "roketin/stellar-connect": "v0.0.15"
    }

接下来,从终端运行 Composer 更新命令

composer update

or

composer require "roketin/stellar-connect"

配置

  1. 打开 config/app.php 并将此行添加到您的 Service Providers 数组中
  Roketin\Providers\RoketinServiceProvider::class
  1. 打开 config/app.php 并将此行添加到您的 Aliases 中
  'Roketin' => Roketin\Facades\RoketinFacade::class
  1. 请将其添加到 .env 文件中
  ROKETIN_API=https://api.stellar.roketin.com
  ROKETIN_PUBLIC=https://api.stellar.roketin.com

  ROKETIN_API_KEY=api_key

如何使用

基本

您可以使用以下方式调用 Roketin 对象:Roketin::model()->module()->get()

    use Roketin;

    $menus = Roketin::menu()->list()->get();
    $pages = Roketin::page()->list()->get();
    $posts = Roketin::post()->list()->get();
    $products = Roketin::product()->list()->get();
    $variants = Roketin::variant()->list()->get();
    $categories = Roketin::category()->list()->get();
    etc..

通过 id/slug 等获取单个对象

    /**
     * Same as fetching object, but in singular form (without 's')
     * the second argument can be id or slug
     * this is dynamic function call to Roketin Engine API
     */

    $menu = Roketin::menu()->show('asc-123123-asxzc')->get();
    $page = Roketin::page()->show('home')->get();
    $post = Roketin::post()->show('lastest-update')->get();

显示

如果您想获取详细信息

    /**
     * @param $id
     */

    $products = Roketin::product()->show($id)->get();
    etc..

条件

通过简单条件获取对象

    /**
     * @param $field
     * @param $operation
     * @param $value
     */

    $posts = Roketin::post()->list()->where('title', 'like', 'vacation')->get();

    //NOTE :
    //It doesn't need to add % if using 'like' operator

通过简单 orWhere 条件获取对象

    /**
     * @param $field
     * @param $operation
     * @param $value
     */

    $posts = Roketin::post()
                        ->list()
                        ->where('title','like','vacation')
                        ->orWhere('title','like','holiday')
                        ->get();

    //NOTE :
    //It doesn't need to add % if using 'like' operator

高级 where 或 orWhere 分组条件

    /**
     * @param $field
     * @param $operation
     * @param $value
     */

    $posts = Roketin::post()
                        ->list()
                        ->where('title','like','vacation')
                        ->orWhere('title','like','holiday')
                        ->where('date','>=','2016-04-10')
                        ->where('date','<=','2016-04-18')
                        ->get();

    //NOTE :
    //It will result query grouping
    // (title like vacation or title like holiday)
    // AND
    // (date >= 2016-04-10 and date <= 2016-04-18 )

排序

通过排序字段获取 Roketin 对象 API

    /**
     * sorting object before fetch
     *
     * @param $field
     * @param $direction (optional) default is ASC
     */

    $posts = Roketin::post()->list()->sortBy('created_at')->get();
    $posts = Roketin::post()->list()->sortBy('created_at', 'DESC')->get();

分页

分页获取对象

    /**
     * paginate object before fetch
     *
     * @param $size default value is 10
     * @param $page (optional)
     */

    $posts = Roketin::post()->list()->paginate(10)->get();
    $posts = Roketin::post()->list()->paginate(10,2)->get();

配送

获取所有可用国家

    $countries = Roketin::country()->list()->get();

获取所有可用省份(目前仅适用于印度尼西亚)

    /**
     * @param $country_id
     */

    $province = Roketin::province()->list('ID')->get();

获取所有可用城市(目前仅适用于印度尼西亚)

    /**
     * @param $province_id
     */

    $cities = Roketin::city()->list(9)->get();

获取所有可用区(目前仅适用于印度尼西亚)

    /**
     * @param $city_id
     */

    $districts = Roketin::district()->list(9)->get();

获取所有可用街区(目前仅适用于印度尼西亚)

    /**
     * @param $district_id
     */

    $subDistricts = Roketin::subDistrict()->list(9)->get();

获取免费配送信息

    $freeShipping = Roketin::shipping()->freeShipping()->show();

社交媒体

获取所有可用社交媒体

    $medias = Roketin::socialMedia()->list()->get();

公司详情

获取所有可用国家

    $company = Roketin::company()->detail()->get();

页面和帖子

获取所有菜单

    $menus = Roketin::menu()->list()->get();

获取所有页面

    $pages = Roketin::post()->list()->get();

获取所有帖子

    $posts = Roketin::post()->list()->get();

获取所有分类帖子

    $categories = Roketin::categoryPost()->list()->get();

远征

获取所有可用远征

    $expeditions = Roketin::expedition()->list()->get();

获取所有可用远征

    $expeditions = Roketin::expedition()->service()->list()->get();

获取配送费用(已弃用,使用远征服务 - 使用以下费用代替)

    $delivery = [
        'origin'        => '501',
        'destination'   => '574',
        'weight'        => 1700,
        'courier'       => 'jne'
    ];

    $expeditions = Roketin::expedition()->cost($delivery);

获取配送费用此版本的 Get Delivery Cost 已实现支持免费配送

    $delivery = [
            "origin" => "78",
            "originType" => "city",
            "destination" => "153",
            "destinationType" => "city",
            "weight" => 1700,
            "courier" => "jne",
            "service" => "YES",
            "purchase" => 8000000
        ];
    $expeditions = Roketin::expedition()->service()->cost($delivery);
    if ($expeditions->meta->status_code == 202) {
        //Covered by freeshipping
    }

银行

获取所有可用银行

    $expeditions = Roketin::bank()->list()->get();

订单

创建销售订单

    /**
     * @param array $generalData
     * @param array $customerData
     * @param array $products
     * @param $bcc(optional), default = null
     */

    $order = [
        "member_id"             => "5b55af8c6f6bfc0c74007955",
        "order_at"              => "2009-09-09",
        "is_create_invoice"     => true,
        "due_date_invoice"      => "2009-09-09",
        "message_from_customer" => "pesan",
        "name"                  => "adin",
        "email"                 => "test@gmail.com",
        "phone"                 => "123123123",
        "address"               => "Bandung",
        "send_invoice"          => true,
        "shipping"              => true,
        "expedition_code"       => "jne",
        "service_code"          => "oke",
        "discounts"             => 10000,
        "voucher_code"          => "voucher12009",
        "tax"                   => 10,
        "shipping_cost"         => 0,
        "sender_id"             => "5b3309076f6bfc0460000b73",
        "products"              =>[
            {
                "name"          => "Sepatu Merah",
                "product_id"    => "5b6184386f6bfc3d18003eca",
                "quantity"      => 1,
                "price"         => 200000,
                "discount"      => 0,
                "add_cost"      => 0,
                "weight"        => 100
            },
            {
                "name"          => "Sendal Merah",
                "product_id"    => "5b6184386f6bfc3d18003ecb",
                "quantity"      => 1,
                "price"         => 30000,
                "discount"      => 0,
                "add_cost"      => 0,
                "weight"        => 100
            },
            {
                "name"          => "Swallow",
                "product_id"    => "5b6184386f6bfc3d18003ecc",
                "quantity"      => 1,
                "price"         => 50000,
                "discount"      => 0,
                "add_cost"      => 0,
                "weight"        => 100
            }
        ]
    ];

    $order = Roketin::salesOrder()->store($order);

搜索销售订单

    /**
     * @param $query
     */

    $order = Roketin::salesOrder()->search($query)->get()

注意

  • 有关详细属性,请参阅销售订单 API 文档这里

创建支付订单

    /**
     * @param $payment
     */

    $image = Roketin::image()->send($request->file('image'));

    $payment = [
        "sales_invoice_id"      => "8b2ac9dc-85b1-49fe-b609-3e0539af2eb6",
        "payment_type"          => "transfer",
        "paid_at"               => "2009-09-09",
        "nominal"               => 10000,
        "company_bank_id"       => "8b29e54e-ba87-487a-9fc2-b8898d902074",
        "bank_name"             => "adin",
        "account_number"        => "0189320123",
        "account_name"          => "adin",
        "card_number"           => "01982301",
        "credit_card_type"      => "credit",
        "transaction_number"    => "T001092381",
        "attachment"            => $image
    ];

    $payment = Roketin::payment()->confirm($payment);

消息

向 Roketin Engine 入口发送消息

    /**
     * @param $sender_name
     * @param $sender_email
     * @param $sender_phone
     * @param $message_title
     * @param $message_body
     * @param $bcc(optional), default = null
     * @param $send_message(optional), default = false
     */

    $msg = Roketin::message()->send(
                    'test',
                    'test@mailinator.com',
                    '123123',
                    'test mesage',
                    'hai',
                    ['bcc@mailinator.com'],
                    false
    );

订阅

向 Roketin Engine 订阅发送订阅

    /**
     * @param $email
     */

    $msg = Roketin::subscribe()->send('test@mailinator.com')

优惠券

检查优惠券的有效性

    /**
     * @param $code
     * @param $voucher_type (optional), default = null
     * voucher type can be giftvoucher (voucher in
     * exchange to money nominal) or
     * other (voucher to exchange to free product)
     * default is voucher_type is other
     */
    $data = [
        'code'           => 'AS123D',
        'total_purchase' => 10000
    ];

    $check = Roketin::voucher()->check($data)

成员

注册新成员

    /*
    * REGISTER
    *
    * register() will return a RMember class which you can use to futher manipulate member
    * register() will throw \Exception if something went wrong (Eg:email already used)
    */
    $register_data = [
        'first_name' => 'Ali', //required
        'last_name' => 'of Ababwa',
        'email' => 'ali@ababwa.com', //required
        'password' => 'secretPassword123!', //required
        'password_confirmation' => 'secretPassword123!', //required
        'addresses' => [ //addresses can be empty [] or null
            [
                'address_type' => 'perkantoran', //address_type can be anything, will be created if not yet exist
                'address' => 'Jl. Asia Afrika No.116, RW.01, Paledang, Kec. Lengkong, Kota Bandung, Jawa Barat 40261',
                'country' => [
                    'label' => 'Indonesia',
                    'value' => 'ID'
                ],
                'province' => [
                    'label' => 'Jawa Barat',
                    'value' => '9'
                ],
                'city' => [
                    'label' => 'Kota Bandung',
                    'value' => '23'
                ],
                'district' => [
                    'label' => 'Kota Cibiru',
                    'value' => '352'
                ],
                'postal_code' => '40524',
                'direction' => 'Depan simpang lima kiri',
                'coordinate' => [
                    'lat' => 12.1232323,
                    'lng' => 23.1232434
                ],
                'main_address' => true,
                'active_status' => true,
                'store_address' => false,
            ], [ //One member can have more than one address
                'address_type' => 'pantai',
                'address' => 'Pangandaran Beach',
                'country' => [
                    'label' => 'Indonesia',
                    'value' => 'ID'
                ],
                'province' => [
                    'label' => 'Jawa Barat',
                    'value' => '9'
                ],
                'city' => [
                    'label' => 'Kota Bandung',
                    'value' => '23'
                ],
                'district' => [
                    'label' => 'Kota Cibiru',
                    'value' => '352'
                ],
                'postal_code' => '40524',
                'direction' => 'Lurus terus',
                'coordinate' => [
                    'lat' => 12.1232323,
                    'lng' => 23.1232434
                ],
                'main_address' => false,
                'store_address' => true,
                'active_status' => true,
            ]
        ],
        'contacts' => [ //contact can be empty or null
            [ //shown bellow are list of all posible contact
                "contact_type" => 1, //phone number
                "phone_number" => "081111112222",
                "emergency_contact" => true,
                "whatsapp" => true,
                "line" => true,
                "main_contact" => true,
                "active_status" => true
            ], [
                'contact_type' => 2, //email
                'email' => 'athuria@pendragon.com',
                'main_contact' => true,
                'active_status' => true
            ], [
                "contact_type" => 3, //skype
                "skype_id" => "1231243132134213",
                "main_id" => true,
                "active_status" => true,
            ], [
                "contact_type" => 4, //website
                "url" => "https://www.google.com",
                "active_status" => true,
            ], [
                "contact_type" => 5, //contact Person
                "name" => "Eve",
                "position" => "Secretary",
                "start_date" => "2019-08-01 15:03:00",
                "end_date" => "2019-08-17 15:03:00",
                "until_now" => true,
                "description" => "lorem ipsum"
            ]
        ]
    ];
    try {
        $member = Roketin::member()->register($register_data);
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

    //If you want roketin to automagicaly send email confirmation and handle it for you, set the second argument of register() to true

    try {
        $member = Roketin::member()->register($register_data, true);
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

    //You can ask roketin to resend email confirmation by using

    $respone = $member->resendEmail();

    //If you don't set it to true you need to handle email confirmation yourself by following these instruction;
    //1. register() will throw an exception telling you that register has succeded. In the response thrown by register() will also be information about member_id and email_confirmation_token, you will use it for the next step
    //2. you would want to send a custom email to the member that contail link with format '{your-custom-url}/handle-confirmation/{id}/{token}' just like forgot password
    //3. In the aforementioned link, you would want to call

    $response = Roketin::member()->handleEmailConfirmation($id, $token);

    //stellar will handle the rest

通过电子邮件登录成员

    /*
     * LOGIN
     * Login App
     *
     * Login() will return a RMember class which you can use to manipulate member
     * login() will throw \Exception if something went wrong (Eg:wrong credential)
     */
    $credential = [
        'email' => 'ali@ababwa.com',
        'password' => 'secretPassword123!'
    ];

    try {
        $member = Roketin::member()->login($credential);
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

    //You can get RMember class for client's current session by using member - getSession
    //NOTE : The routes that call register, login, getSession, and logout have to be within the 'web' middleware group in order to use these feature below AND DONT disrupt the application flow like using dd() or die()

    try {
        $member = Roketin::member()->getSession();
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

    //And log out by using member - logout
    $response = Roketin::member()->logout();

获取成员详情

    /*
     * SHOW
     * There's two way you can get member's detail;
     */
    //1. By its id
    $member_data = Roketin::member()->show('5d4a9d3ca051e83db4000148')->get();
    //2. Or, by its object
    $member_data = $member->show()->get();

更新成员的资料

    /*
     * UPDATE PROFILE
     *
     * There's also two way you can change member's detail
     * Note : To change its contact, and address, use their respective update method
     * update() will throw \Exception if something went wrong (Eg:wrong field)
     */
    $change_data = [
        'first_name' => 'Ali',
        'last_name' => 'of Ababwa',
    ];

    try {
        //1. By its id
        Roketin::member()->update($change_data, '5d4a9d3ca051e83db4000148');
        //2. Or, by its object
        $member->update($change_data);
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

更改成员的密码

    /*
     * CHANGE PASSWORD
     *
     * changePassword() will throw \Exception if something went wrong (Eg:failed password confirmation)
     */
    $change_data_pass = [
        'old_password' => 'secretPassword123*',
        'new_password' => 'secretPassword123*',
        'new_password_confirmation' => 'secretPassword123*'
    ];

    try {
        $member->changePassword($change_data_pass);
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

忘记密码处理程序

    /*
     * Member - Forgot Password
     *
     * forgotPassword() will return member_id and a token to be used in handle forgot_password
     * if you want stellar to automagically send email and handle forgot password for you, set $send_email to true
     * forgotPassword() will throw \Exception if something went wrong (Eg: invalid email)
     */
    try {
        $credential = Roketin::member()->forgotPassword('ali@ababwa.com');
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

    //You would want to send an email that carries $credential.user_id, $credential.token and a link to a website that handle forgot password request,
    //There you would want to call this method using the aforementioned values in $credential as parameters

    $params = [
        'new_password' => 'notSoSecret123!',
        'new_password_confirmation' => 'notSoSecret123!',
    ];
    try {
        Roketin::member()->handleForgotPassword($params, $credential->data->user_id, $credential->data->token);
    } catch(\Exception $exception) {
        return response()->json(json_decode($exception->getMessage()));
    }

获取成员的订单历史记录

    $order = $member->salesOrder()->list()->get();

成员-地址

获取成员的地址

    /*
     * INDEX
     *
     * There's two way you can index address
     * Everything else is as usual
     */
    //1. Show all address recorded for your company
    $address_data = Roketin::address()->list()->get();

    //2. Show only the address that a member have
    $address_data = $member->address()->list()->get();

逐个显示详细的成员地址

    /*
     * SHOW
     * Show the detailed information of an address
     *
     * There's two way you can show address
     * Everything else is as usual
     */
    //1. Show resource as usual
    $address_data = Roketin::address()->show('5d4a9d3ca051e83db4000149')->get();

    //2. Just like above, but with stricker security, only member that have the address can show the resource
    $address_data = $member->address()->show('5d4a9d3ca051e83db4000149')->get();

为成员存储新的地址

    /*
     * STORE
     * Store an address to scm and pair it with the designated member
     *
     * There's two way you can store address
     */
    $params = [
        'address_type' => 'perkantoran',
        'address' => 'TAIPEI 102, 101th floor',
        'country' => [
            'label' => 'Indonesia',
            'value' => 'ID'
        ],
        'province' => [
            'label' => 'JAWA BARAT',
            'value' => '32'
        ],
        'city' => [
            'label' => 'KABUPATEN BANDUNG',
            'value' => '3204'
        ],
        'district' => [
            'label' => 'CIDEWAY',
            'value' => '3204010'
        ],
        'postal_code' => '40524',
        'direction' => 'Bunderan tamrin jangan belok belok',
        'coordinate' => [
            'lat' => 12.1232323,
            'lng' => 23.1232434
        ],
        'main_address' => false,
        'store_address' => false,
        'active_status' => true,
    ];
    //1. Using member's id
    $result = Roketin::address()->store($params, '5d4a9d3ca051e83db4000148');
    //2. Using member's object
    $result = $member->address()->store($params);

更新成员的现有地址

    /**
     * UPDATE
     * Update an address
     *
     * There's two way you can store address,
     * But both requires address_id as parameters
     * because member - address is one - many relationship
     */
    $params = [
        'address' => 'TAIPEI 101, 101th floor penthouse',
        'main_address' => true,
        'store_address' => false,
    ];
    //1. Directly using Roketin Facade
    $result = Roketin::address()->update($params, '5d503a1ca051e83c50001ff3');
    //2. Using member's object, same as above but with more security,
    //   only address coresponding member can update/change it
    $result = $member->address()->update($params, '5d41343aa051e856940024aa');

删除成员的现有地址

    /**
     * DESTROY
     * Delete an address from the database
     *
     * There's two way you can store address,
     * But both requires address_id as parameters
     * because member - address is one - many relationship
     */
    //1. Directly using Roketin Facade
    $result = Roketin::address()->destroy('5d4d4608a051e83e28004a03');

    //2. Using member's object, same as above but with more security,
    //   only address coresponding member can update/change it
    $result = $member->address()->destroy('5d3e7f9ca051e8bb8400ca00');

成员联系

获取成员的联系信息

   /*
    * INDEX
    *
    * There's two way you can index contact
    * Everything else is as usual
    */
    //1. Show all contact recorded for your company
    $contact_data = Roketin::contact()->list()->get();

    //2. Show only the contact that a member have
    $contact_data = $member->contact()->list()->get();

获取联系信息的详细信息

    /*
     * SHOW
     * Show the detailed information of a contact
     *
     * There's two way you can show contact
     * Everything else is as usual
     */
    //1. Show resource as usual
    $contact_data = Roketin::contact()->show('5d523b89a051e83aa4006b16')->get();

    //2. Just like above, but with stricker security, only member that have the contact can show the resource
    $contact_data = $member->contact()->show('5d523b89a051e83aa4006b16')->get();

为成员存储新的联系信息

    /*
     * STORE
     * Store a contact to scm and pair it with the designated member
     *
     * There's two way you can store address
     */
    //Shown below are the alternatives for member store parameter
    $params = [
        "contact_type" => 1, //phone number
        "phone_number" => "081111112222",
        "emergency_contact" => true,
        "whatsapp" => true,
        "line" => true,
        "main_contact" => true,
        "active_status" => true
    ];
    $params = [
        'contact_type' => 2, //email
        'email' => 'athuria@pendragon.com',
        'main_contact' => true,
        'active_status' => true
    ];
    $params = [
        "contact_type" => 3, //skype
        "skype_id" => "1231243132134213",
        "main_id" => true,
        "active_status" => true,
    ];
    $params = [
        "contact_type" => 4, //website
        "url" => "https://www.google.com",
        "active_status" => true,
    ];
    $params = [
        "contact_type" => 5, //Contact Person
        "name" => "Eve",
        "position" => "Secretary",
        "start_date" => "2019-08-01 15:03:00",
        "end_date" => "2019-08-17 15:03:00",
        "until_now" => true,
        "description" => "lorem ipsum"
    ];

    //1. Using member's id
    $result = Roketin::contact()->store($params, '5d4a9d3ca051e83db4000148');
    //2. Using member's object
    $result = $member->contact()->store($params);

更新成员的现有联系信息

    /**
     * UPDATE
     * Update a contact
     *
     * There's two way you can store contact,
     * But both requires address_id as parameters
     * because member - contact is one - many relationship
     */
    $params = [
        'contact_type' => 2,
        'email' => 'athuria@pendragon.com',
        'main_contact' => true,
        'active_status' => true
    ];
    //1. Directly using Roketin Facade
    $result = Roketin::contact()->update($params, '5d503a1ca051e83c50001ff3');
    //2. Using member's object, same as above but with more security,
    //   only contact's coresponding member can update/change it
    $result = $member->contact()->update($params, '5d41343aa051e856940024aa');

删除成员的现有联系信息

    /**
     * DESTROY
     * Delete a contact from the database
     *
     * There's two way you can store contact,
     * But both requires contact_id as parameters
     * because member - contact is one - many relationship
     */
    //1. Directly using Roketin Facade
    $result = Roketin::contact()->destroy('5d4d4608a051e83e28004a03');

    //2. Using member's object, same as above but with more security,
    //only contact's coresponding member can update/change it
    $result = $member->contact()->destroy('5d3e7f9ca051e8bb8400ca00');

成员-心愿单

获取心愿单

    /*
    * INDEX
    *
    * There's two way you can fetch contact
    * Everything else is as usual
    */
    //1. Show all wishlist recorded for your company
    $wishlist = Roketin::wishlist()->list()->get();

    //2. Show only the wishlist that a member have
    $wishlist = $member->wishlist()->list()->get();

通过简单条件获取心愿单

    /**
     * @param $user_id
     */

    $wishlist = Roketin::wishlist()
                        ->list()
                        ->where('variant_id','like','abc1234')
                        ->get();

添加新的心愿单

    /**
     * STORE
     * Store a contact to scm and pair it with the designated member
     *
     * There's two way you can store wishlist
     * @param $user_id
     * @param $variant_id
     */

    $data = [
        "variant_id" => "5b55af8c6f6bfc0c74007955",
    ];
    // By member's id
    $wishlist = Roketin::wishlist()->store($data, '5b55af8c6f6bfc0c74007955');

    // By its object
    $wishlist = $member->store($data);

删除心愿单

    /**
     * Delete
     * Delete wishlist of a member
     *
     * There's two way you can store wishlist
     * @param $user_id
     * @param $variant_id
     */

    $data = [
        "variant_id" => "5b55af8c6f6bfc0c74007955",
    ];

    $wishlist = Roketin::wishlist()->delete($data, '5b55af8c6f6bfc0c74007955');
    //or
    $wishlist = $member->wishlist()->delete($data);

其他

按分类获取产品变体

    /**
     * @param $category_name
     * @return variants object
     */

    Roketin::product()->list()->categories('baju')->get();

    or

    Roketin::product()->list()->categories(['baju'])->get();

按标签获取产品变体

    /**
     * @param $category_name
     * @return variants object
     */

    Roketin::product()->list()->tags('baju')->get();

    or

    Roketin::product()->list()->tags(['baju'])->get();

按关系排序产品

    /**
     * @param $category_name
     * @return variants object
     */

    Roketin::product()->list()->sortBy('price', 'ASC', 'variants')->get();