ktnw/curd_support

curd enhancements for laravel

dev-master 2023-07-10 05:47 UTC

This package is auto-updated.

Last update: 2024-04-10 07:30:36 UTC


README

介绍

封装公用的curd操作.
已集成library:

  1. prettus/l5-repository
  2. league/fractal
  3. illuminate/database

使用说明

step1: 引入

composer require ktnw/curd_support

step2: 发布

php artisan vendor:publish --provider="Prettus\Repository\Providers\RepositoryServiceProvider"  

step3: 根据实际需求,修改step2中生成的配置文件--repository.php

step4: 创建service层接口和实现

   service层接口继承: Ktnw\CurdSupport\Services\BaseService <br>
   service层实现继承: Ktnw\CurdSupport\Services\Impl\BaseServiceImpl <br>
   示例如下:
namespace App\Services;

use Ktnw\CurdSupport\Services\BaseService;

interface UserService extends BaseService {

}
namespace App\Services\Impl;

use App\Services\UserService;
use Ktnw\CurdSupport\Services\Impl\BaseServiceImpl;

class UserServiceImpl extends BaseServiceImpl implements UserService
{
    public function __construct()
    {
    }
}

即可调用BaseService中提供的接口方法。

step5: 若需对BaseService和BaseServiceImpl进行扩展,可自行继承后,进行扩展。

详细使用示例

下面示例包含完整的增删查改示例

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Params\Query\UserQuery;
use App\Params\UserParam;
use App\Responses\ResponseBody;
use App\Utils\EncryptUtils;
use App\Wrappers\query\UserQueryWrapper;
use App\Wrappers\save\UserSaveWrapper;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Ktnw\CurdSupport\Services\BaseService;
use Ktnw\CurdSupport\Wrappers\QueryConstants;

class UserController extends Controller
{
    private $baseService;

    public function __construct(BaseService $baseService)
    {
        $this->baseService = $baseService;
    }

    /**
     * 查询用户
     * @param Request $request
     * @param int $userId
     * @return JsonResponse
     * @throws Exception
     */
    public function find(Request $request, int $userId): JsonResponse
    {
        $user = $this->baseService->findOne($userId, User::class, false);
        if (!$user) {
            return ResponseBody::wrong("未查询到用户");
        }
        return ResponseBody::success($user);
    }

    /**
     * 删除用户
     * @throws Exception
     */
    public function delete(int $userId): JsonResponse
    {
        $r = $this->baseService->delete($userId, User::class, false);
        return $r ? ResponseBody::success("操作成功") : ResponseBody::wrong("操作失败");
    }

    /**
     * 保存用户
     * @param Request $request
     * @param UserParam $param
     * @return JsonResponse
     * @throws Exception
     */
    public function save(Request $request, UserParam $param): JsonResponse
    {
        if ($param->getOpType() == 1) {
            // 新增
            $param->setId(null);
        }
        // 加密密码
        if (!empty($param->getPassword())) {
            $param->setPassword(EncryptUtils::hashEncrypt($param->getPassword()));
        }
        $r = $this->baseService->saveOrUpdate($param, User::class, new UserSaveWrapper());
        return $r ? ResponseBody::success("操作成功") : ResponseBody::wrong("操作失败");
    }

    /**
     * 查询列表
     * @param Request $request
     * @param UserQuery $userQuery
     * @return JsonResponse
     */
    public function list(Request $request, UserQuery $userQuery): JsonResponse
    {
        $queryWrapper  = new UserQueryWrapper(QueryConstants::DB_QUERY, $userQuery, User::class);
        $wrapperParams = $queryWrapper->initQueryWrapper();
        return ResponseBody::success($this->baseService->findList($wrapperParams));
    }
}

<?php

namespace App\Services;

use App\Models\User;
use Ktnw\CurdSupport\Services\BaseService;

interface UserService extends BaseService
{

    /**
     * 获取用户
     * @param string $userName 用户名
     * @param bool $isInstance 是否返回实例 true-返回示例; false-返回数组
     * @return User|array
     */
    public function findByUserName(string $userName, bool $isInstance = true);
}

<?php

namespace App\Services\Impl;

use App\Models\User;
use App\Services\UserService;
use Exception;
use Ktnw\CurdSupport\Services\Impl\BaseServiceImpl;

class UserServiceImpl extends BaseServiceImpl implements UserService
{
    public function __construct()
    {

    }

    /**
     * 获取用户
     * @throws Exception
     */
    public function findByUserName(string $userName, bool $isInstance = true)
    {
        $where   = [];
        $where[] = ['user_name', '=', $userName];
        return $this->findOneByKeys($where, User::class, $isInstance);
    }
}

<?php
/**
 * Created by PhpStorm.
 * User: youqingsong
 * Date: 2022/2/10
 * Time: 10:13
 */

namespace App\Wrappers\save;

use App\Params\UserParam;
use App\Services\UserService;
use Exception;
use Ktnw\CurdSupport\Params\AbstractBaseParams;
use Ktnw\CurdSupport\Wrappers\SaveOrUpdateWrapper;

class UserSaveWrapper extends SaveOrUpdateWrapper
{

    private $userService;

    public function __construct()
    {
        $this->userService = $this->getUserService();
    }


    /**
     * @throws Exception
     */
    function verify(AbstractBaseParams $params): bool
    {
        return $this->check($params);
    }

    /**
     * @return UserService
     */
    private function getUserService(): UserService
    {
        return resolve(UserService::class);
    }

    /**
     * @throws Exception
     */
    private function check(UserParam $params): bool
    {
        $user = $this->userService->findByUserName($params->getUserName());
        if ($user != null && $user["id"] != $params->getId()) {
            throw new Exception("用户名已存在");
        }
        return true;
    }

}

<?php

namespace App\Wrappers\query;

use App\Params\Query\UserQuery;
use Ktnw\CurdSupport\Utils\QueryUtils;
use Ktnw\CurdSupport\Wrappers\BaseQueryWrapper;
use Ktnw\CurdSupport\Wrappers\QueryConstants;
use Ktnw\CurdSupport\Wrappers\QueryWrapperParams;

class UserQueryWrapper extends BaseQueryWrapper
{
    public $queryType;
    public $query;

    /**
     * @param int $queryType
     * @param UserQuery $query
     * @param string|null $modelClass
     */
    public function __construct(int $queryType, UserQuery $query, string $modelClass = null)
    {
        parent::__construct($queryType, null, $modelClass);
        $this->queryType = $queryType;
        $this->query     = $query;
    }

    /**
     * 根据查询类型返回查询时需要的查询条件及参数
     * @return QueryWrapperParams
     */
    public function initQueryWrapper(): QueryWrapperParams
    {
        return $this->queryType == QueryConstants::DB_MODEL ? $this->initModelQuery() : $this->initSqlQuery();
    }

    /**
     * ORM查询初始化查询条件及参数
     * 查询条件格式和DB::table()需要的一致
     */
    private function initModelQuery(): QueryWrapperParams
    {
        $where      = QueryUtils::queryCriteria($this->query, $this->modelClass);
        $inWhere    = [];
        $notInWhere = [];
        $orWhere    = [];
        $findColumn = [];
        $orderBy    = [];

        $params = new QueryWrapperParams($this->queryType);
        $params->setModelClass($this->modelClass);
        $params->setPage($this->query->getPage());
        $params->setSize($this->query->getSize());
        $params->setWhere($where);
        $params->setInWhere($inWhere);
        $params->setOrWhere($orWhere);
        $params->setNotInWhere($notInWhere);
        $params->setFindColumn($findColumn);
        $params->setOrderBy($orderBy);
        $params->setUsePresenter($this->query->getUsePresenter());

        return $params;
    }

    /**
     * 原生SQL查询初始化查询条件及参数
     */
    private function initSqlQuery(): QueryWrapperParams
    {
        $totalSql = "";
        $sql      = "SELECT * FROM users u where 1 ";
        $p        = [];
        $userName = $this->query->getUserName();
        $phone = $this->query->getPhone();
        if ($userName) {
            $sql .= ' AND u.user_name = ? ';
            $p[] = $userName;
        }
        if ($phone) {
            $sql .= ' AND u.phone = ? ';
            $p[] = $phone;
        }

        $params   = new QueryWrapperParams($this->queryType);
        $params->setPage($this->query->getPage());
        $params->setSize($this->query->getSize());
        $params->setTotalSql($totalSql);
        $params->setSql($sql);
        $params->setParams($p);

        return $params;
    }

}

<?php

namespace App\Utils;

use Illuminate\Support\Facades\Hash;

/**
 * 加密工具
 */
class EncryptUtils
{
    /**
     * Hash加密
     * @param $pwd
     * @return string
     */
    public static function hashEncrypt($pwd): string
    {
        return Hash::make($pwd);
    }

    /**
     * Hash密码校验
     * @param $pwd string 明文密码
     * @param $encryptPassword string 加密后的密码
     * @return bool
     */
    public static function hashCheck(string $pwd, string $encryptPassword): bool
    {
        return Hash::check($pwd, $encryptPassword);
    }
}

<?php

namespace App\Utils;
/**
 * 时间工具类
 */
class DateUtils
{
    /**
     * 获取当前的日期字符串
     */
    public static function getCurDateStr()
    {
        return date("Y-m-d", time());
    }

    /**
     * 时间戳转为日期格式
     * @param $timestamp int 时间戳精确到秒
     * @return string
     */
    public static function timestampToDateStr(int $timestamp): string
    {
        return date('Y-m-d H:i:s', $timestamp);
    }

    /**
     * 返回当前的毫秒时间戳
     */
    public static function getMillisecond(): float
    {
        list($t1, $t2) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
    }
}

<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Ktnw\CurdSupport\Traits\BaseModelTrait;
use Illuminate\Foundation\Auth\User as AuthUser;
use Tymon\JWTAuth\Contracts\JWTSubject;

/**
 * Class User.
 *
 * @package namespace App\Models;
 */
class User extends AuthUser implements JWTSubject
{
    use Notifiable;
    use BaseModelTrait;
    protected $fillable   = [];
    protected $hidden     = [];
    protected $table      = 'users';
    public    $timestamps = FALSE;

    /**
     * Get the identifier that will be stored in the subject claim of the JWT.
     *
     * @return mixed
     */
    public function getJWTIdentifier()
    {
        return $this->getKey();
    }

    /**
     * Return a key value array, containing any custom claims to be added to the JWT.
     *
     * @return array
     */
    public function getJWTCustomClaims()
    {
        return [];
    }


    /**
     * 重写getAuthPassword
     * 可根据业务需求设置
     * CustomEloquentUserProvider的validateCredentials()会用到
     * @return string
     */
    public function getAuthPassword()
    {
        return md5($this->getAttributeValue("id") . $this->getAttributeValue("user_name"));
    }

}

<?php
/**
 * Created by PhpStorm.
 * User: youqingsong
 * Date: 2020/9/17
 * Time: 9:03
 */

namespace App\Responses;

use Illuminate\Http\JsonResponse;

/**
 * api接口的响应类
 */
class ResponseBody
{
    // 响应码
    private $code;

    // 提示信息
    private $message;

    // 响应数据
    private $data;

    public function __construct($code, $message, $data = [])
    {
        $this->code    = $code;
        $this->message = $message;
        $this->data    = $data;
    }

    public static function success($data = []): JsonResponse
    {
        $data = empty($data) ? [] : $data;
        return (new ResponseBody(ResponseConstant::SUCCESS, 'ok', $data))->out();
    }

    public static function error($code, $msg = ''): JsonResponse
    {
        return (new ResponseBody(empty($code) ? ResponseConstant::FAIL : $code, $msg, []))->out();
    }

    public static function wrong($msg = RespCode::OP_FAIL, $code = ''): JsonResponse
    {
        return (new ResponseBody(empty($code) ? ResponseConstant::FAIL : $code, $msg, []))->out();
    }

    public static function respCode($resp, $msg = ''): JsonResponse
    {
        return (new ResponseBody($resp['code'], empty($msg) ? $resp['message'] : $msg, []))->out();
    }

    public static function output(array $data): JsonResponse
    {
        return response()->json($data)
            ->header('Content-Type', 'text/json')
            ->setEncodingOptions(JSON_UNESCAPED_UNICODE);
    }


    private function out(): JsonResponse
    {
        return response()->json($this->object_to_array($this))
            ->header('Content-Type', 'text/json')
            ->setEncodingOptions(JSON_UNESCAPED_UNICODE);
    }


    /**
     * 对象转换数组
     * @param $obj
     * @return array
     */
    private function object_to_array($obj): array
    {
        if (!is_array($obj) && !is_object($obj)) {
            return $obj;
        }
        $_arr = is_object($obj) ? get_object_vars($obj) : $obj;
        $arr  = [];
        foreach ($_arr as $key => $val) {
            $val       = (is_array($val)) || is_object($val) ? $this->object_to_array($val) : $val;
            $arr[$key] = $val;
        }
        return $arr;
    }

}

<?php

namespace App\Responses;
/**
 * 统一返回常量设置
 */
class ResponseConstant
{
    /**
     * 成功
     */
    const SUCCESS = 1;

    /**
     * 失败
     */
    const FAIL = -1;

    /**
     * 登录未授权
     */
    const UNAUTHORIZED = 401;
}

参与贡献

  1. Fork 本仓库
  2. 新建 Feat_xxx 分支
  3. 提交代码
  4. 新建 Pull Request

特技

  1. 使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md
  2. Gitee 官方博客 blog.gitee.com
  3. 你可以 https://gitee.com/explore 这个地址来了解 Gitee 上的优秀开源项目
  4. GVP 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
  5. Gitee 官方提供的使用手册 https://gitee.com/help
  6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 https://gitee.com/gitee-stars/