BaseLogic.php 8.5 KB
<?php

namespace App\Http\Logic\Bside;

use App\Enums\Common\Code;
use App\Exceptions\BsideGlobalException;
use App\Helper\Arrays;
use Illuminate\Support\Facades\Cache;

/**
 * @notes: 逻辑层基类 控制器调用 统一返回 统一抛出异常
 */
class BaseLogic
{
    protected $model;

    protected  $requestAll;

    protected $is_cache = true; //是否缓存数据

    public function __construct()
    {
        $this->requestAll = request()->all();
    }

    /**
     * @notes: 请简要描述方法功能
     * @param array $data
     * @return array
     */
    public function success($data = [])
    {
        return $data;
    }

    /**
     * @notes: 错误抛出
     * @param string $code
     * @param string $message
     * @throws BsideGlobalException
     */
    public function fail($message = "", string $code = Code::SYSTEM_ERROR)
    {
        throw new BsideGlobalException($code, $message);
    }


    /**
     * 列表
     * @param array $map
     * @param array $sort
     * @param int $limit
     * @return array
     * @author zbj
     * @date 2023/4/13
     */
    public function getList($map = [], $sort = ['id' => 'desc'], $limit = 20)
    {
        // 闭包查询条件格式化
        $query = $this->formatQuery($map);

        // 排序(支持多重排序)
        $query = $query->when($sort, function ($query, $sort) {
            foreach ($sort as $k=>$v) {
                $query->orderBy($k, $v);
            }
        });

        // 数据分页设置
        if ($limit) {
            $result = $query->simplePaginate();
        }else{
            $result = $query->get();
        }

        return $this->success($result ? $result->toArray() : []);
    }


    /**
     * 详情
     * @param $id
     * @return
     * @author zbj
     * @date 2023/4/13
     */
    public function getInfo($id)
    {
        if($this->is_cache){
            $info = Cache::get($this->getInfoCacheKey($id));
            if (!$info) {
                $info = $this->model->find($id);
                if($info){
                    Cache::put($this->getInfoCacheKey($id), $info);
                }
            }
        }else{
            $info = $this->model->find($id);
        }
        return $this->success($info->toArray());
    }

    /**
     * 保存
     * @param $param
     * @return array
     * @throws BsideGlobalException
     * @author zbj
     * @date 2023/4/13
     */
    public function save($param){
        if(empty($param['id'])){
            $param['created_at'] = $param['updated_at'] = date('Y-m-d H:i:s');
            $res = $this->model->insert($param);
        }else{
            $info = $this->getInfo($param['id']);
            if(!$info){
                $this->fail('数据不存在或者已经删除');
            }
            $param['updated_at'] = date('Y-m-d H:i:s');
            $res = $this->model->where('id', $param['id'])->update($param);
        }
        if($res){
            //清缓存
            if($this->is_cache && !empty($param['id'])){
                Cache::forget($this->getInfoCacheKey($param['id']));
            }
            return $this->success();
        }else{
            $this->fail('保存失败');
        }
    }

    /**
     * 批量删除
     * @param $ids
     * @return array
     * @throws BsideGlobalException
     * @author zbj
     * @date 2023/4/13
     */
    public function delete($ids){
        $ids = array_filter(Arrays::splitFilterToArray($ids), 'intval');
        if(!$ids){
            $this->fail('ID不能为空');
        }
        $map[] = ['id', 'in', $ids];
        $res = $this->formatQuery($map)->delete();
        if($res){
            if($this->is_cache && !empty($param['id'])){
                Cache::forget($this->getInfoCacheKey($param['id']));
            }
            return $this->success();
        }else{
            $this->fail('删除失败');
        }
    }

    /**
     * @param $id
     * @return string
     * @author zbj
     * @date 2023/4/13
     */
    public function getInfoCacheKey($id){
        return $this->model->getTable() . '_info_' . $id;
    }

    /**
     * 格式化查询条件
     * @param $map
     * @return mixed
     * @author zbj
     * @date 2023/4/13
     */
    public function formatQuery($map, $model = '')
    {
        $model = $model ?: $this->model;
        $query = $model->where(function ($query) use ($map) {
            foreach ($map as $v) {
                if ($v instanceof \Closure) {
                    $query = $query->where($v);
                    continue;
                }
                // 判断是否是键值对类型
                if (key($v) !== 0) {
                    $key = key($v);
                    $val = $v[$key];
                    $v = [$key, is_array($val) ? 'in' : '=', $val];
                }
                switch ($v[1]) {
                    case 'like':
                        // like查询 ['name|title', 'like', '%a%']
                        if (strpos($v[0], '|') !== false) {
                            $query->where(function ($query) use ($v) {
                                $item = explode('|', $v[0]);
                                foreach ($item as $vo) {
                                    $query->orWhere($vo, $v[1], $v[2]);
                                }
                            });
                        } else {
                            $query->where($v[0], $v[1], $v[2]);
                        }
                        break;
                    case 'in':
                        // in查询 ['id', 'in', [1,2,3]]
                        if (!is_array($v[2])) {
                            $v[2] = explode(',', $v[2]);
                        }
                        $query->whereIn($v[0], $v[2]);
                        break;
                    case 'not in':
                        // not in查询 ['id', 'not in', [1,2,3]]
                        if (!is_array($v[2])) {
                            $v[2] = explode(',', $v[2]);
                        }
                        $query->whereNotIn($v[0], $v[2]);
                        break;
                    case 'between':
                        // between查询 ['created_at', 'between', ['xxx', 'xxx]]
                        if (!is_array($v[2])) {
                            $v[2] = explode(',', $v[2]);
                        }
                        $query->whereBetween($v[0], $v[2]);
                        break;
                    case 'not between':
                        // not between查询 ['created_at', 'not between', ['xxx', 'xxx]]
                        if (!is_array($v[2])) {
                            $v[2] = explode(',', $v[2]);
                        }
                        $query->whereNotBetween($v[0], $v[2]);
                        break;
                    case 'null':
                        // null查询 ['deleted_at', 'null']
                        $query->whereNull($v[0]);
                        break;
                    case "not null":
                        // not null查询 ['deleted_at', 'not null']
                        $query->whereNotNull($v[0]);
                        break;
                    case "or":
                        // or查询  [[['status'=>1],['status'=>2]], 'or'];
                        //格式:or (status=1 and status=2)
                        $where = $v[0];
                        $query->orWhere(function ($query) use ($where) {
                            // 递归解析查询条件
                            $this->formatQuery($where, $query);
                        });
                        break;
                    case 'xor':
                        // xor查询 [[['status'=>1],['status'=>2]], 'xor'];
                        // 格式:and (status=1 or status=2)
                        $where = $v[0];
                        $query->where(function ($query) use ($where) {
                            foreach ($where as $w) {
                                $query->orWhere(function ($query) use ($w) {
                                    // 递归解析查询条件
                                    $this->formatQuery([$w], $query);
                                });
                            }
                        });
                        break;
                    default:
                        // 常规查询
                        if (count($v) == 2) {
                            $query->where($v[0], '=', $v[1]);
                        } else {
                            $query->where($v[0], $v[1], $v[2]);
                        }
                        break;
                }
            }
        });
        return $query;
    }
}