Laravel 代码复用思路分享

最近刚好写到这种逻辑, 贴出来分享写, 增加点新思路~
尤其是这两个排序的方法, 可能在许多地方都会用到, 非常的方便啊~~

<?php

namespace App\Services\Shop;

use App\Models\ShopGoodsSku;
use App\Services\BaseService;
use App\Models\ShopGoods as Model;

class GoodsService extends BaseService
{
    /**
     * 只需要获取6条数据的情况
     */
    public function homeNewGoods()
    {
        return $this->newGoodsQuery()->limit(6)->get();
    }

    /**
     * 正常的分页列表
     */
    public function newGoods($sales, $price)
    {
        $query = $this->newGoodsQuery();

        // 这里的排序单独提出来, 其他逻辑可以复用
        $this->salesSort($query, $sales);

        $this->priceSort($query, $price);

        return $query->paginate(10);
    }

    /**
     * 重复的 query
     */
    public function newGoodsQuery()
    {
        return Model::with([
            'skus' => fn($query) => $query->orderBy('price')->orderBy('integral_price'),
        ])->where(['status' => Model::STATUS_ON, 'is_new' => 1])->orderByDesc('_sort');
    }

    /**
     * 销量排序
     *
     * 提出来, 方便复用
     * 这个地方用 in_array 和 三目运算符, 代码可以更少, 不过现在这样貌似更易读
     */
    public function salesSort($query, $sales)
    {
        if ($sales == 1) {
            // 销量升序
            $query->withSum('order_finish', 'number')->orderBy('order_finish_sum_number');
        } else if ($sales == 2) {
            // 销量降序
            $query->withSum('order_finish', 'number')->orderByDesc('order_finish_sum_number');
        }
        // 仅 1 / 2 触发排序, 所以这里不需要 else
    }

    /**
     * 价格排序
     *
     * 提出来, 方便复用
     */
    public function priceSort($query, $price)
    {
        $integralQuery = ShopGoodsSku::select('integral_price')
            ->whereColumn('goods_id', 'shop_goods.id')
            ->orderBy('integral_price')
            ->limit(1);

        $priceQuery = ShopGoodsSku::select('price')
            ->whereColumn('goods_id', 'shop_goods.id')
            ->orderBy('price')
            ->limit(1);

        switch ($price) {
            case 1:
                // 积分价格升序
                $query->orderBy($integralQuery);
                break;
            case 2:
                // 积分价格降序
                $query->orderByDesc($integralQuery);
                break;
            case 3:
                // 现金价格升序
                $query->orderBy($priceQuery);
                break;
            case 4:
                // 现金价格降序
                $query->orderByDesc($priceQuery);
                break;
        }
    }
}

再加上 Json Resource , 大多数接口在控制器都是一行代码, 简直赏心悦目🤔
欢迎探讨

本作品采用《CC 协议》,转载必须注明作者和本文链接
海到无涯天作案,山登绝顶我为峰
slowlyo
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 4

写成trait更方便吧

1年前 评论
slowlyo (楼主) 1年前

很不错,个人更喜欢这种标准面向对象的写法,而不是trait

1年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!