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-03-19 09:11:59 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/