ktnw / curd_support
curd enhancements for laravel
    dev-master
    2024-07-19 07:45 UTC
Requires
- illuminate/database: ~5.0|~6.0|~7.0|^8.0
- league/fractal: 1.0.x-dev
- prettus/l5-repository: ^2.7
This package is auto-updated.
Last update: 2025-10-19 10:18:47 UTC
README
介绍
封装公用的curd操作. 
已集成library:
- prettus/l5-repository
- league/fractal
- 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;
}
参与贡献
- Fork 本仓库
- 新建 Feat_xxx 分支
- 提交代码
- 新建 Pull Request
特技
- 使用 Readme_XXX.md 来支持不同的语言,例如 Readme_en.md, Readme_zh.md
- Gitee 官方博客 blog.gitee.com
- 你可以 https://gitee.com/explore 这个地址来了解 Gitee 上的优秀开源项目
- GVP 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
- Gitee 官方提供的使用手册 https://gitee.com/help
- Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 https://gitee.com/gitee-stars/