作者 赵彬吉

update

... ... @@ -9,6 +9,7 @@ use App\Utils\EncryptUtils;
use App\Utils\LogUtils;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
... ... @@ -135,6 +136,11 @@ class Handler extends ExceptionHandler
//开启debug 错误原样输出
$debub = config('app.debug');
$message = $debub ? $message : ($code->description ?? $message);
//请求参数错误 输出具体错误信息
if($code == Code::USER_PARAMS_ERROE()){
$message = Arr::first(Arr::first($exception->errors()));
}
$response = [
'code' => $code,
'message' => $message
... ...
<?php
namespace App\Helper;
/**
* 验证
*/
class Arrays
{
/**
* 把返回的数据集转换成Tree
* @param $list
* @param string $pk
* @param string $pid
* @param string $child
* @param int $root
* @return array
* @author zbj
* @date 2023/4/13
*/
public static function listToTree($list, $pk = 'id', $pid = 'pid', $child = 'children', $root = 0)
{
// 创建Tree
$tree = array();
if (is_array($list)) {
// 创建基于主键的数组引用
$refer = array();
foreach ($list as $key => $data) {
$refer[$data[$pk]] = &$list[$key];
}
foreach ($list as $key => $data) {
// 判断是否存在parent
$parentId = $data[$pid];
if ($root == $parentId) {
$tree[] = &$list[$key];
} else {
if (isset($refer[$parentId])) {
$parent = &$refer[$parentId];
$parent[$child][] = &$list[$key];
}
}
}
}
return $tree;
}
/**
* 分隔字符串成数组并按照指定的函数过滤数组
* @param $string
* @param string $filters
* @param string $delimiter
* @return array|false|string[]
* @author zbj
* @date 2023/4/13
*/
public static function splitFilterToArray($string, $filters = 'trim', $delimiter = ',')
{
if (!$string) {
return [];
}
$data = !is_array($string) ? explode($delimiter, $string) : $string;
$filters = explode(',', $filters);
if (!$filters) {//没有值或者没有过滤函数
return $data;
}
//过滤
foreach ($filters as $fun) {
if (!function_exists($fun)) {
continue;
}
$data = array_map($fun, $data);
}
return $data;
}
}
... ...
... ... @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Bside;
use App\Enums\Common\Code;
use App\Http\Controllers\Controller;
use App\Utils\EncryptUtils;
use Illuminate\Http\JsonResponse;
use \Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Http\Exceptions\HttpResponseException;
... ... @@ -51,13 +52,13 @@ class BaseController extends Controller
/**
* 成功返回
* @param array $data
* @param string $code
* @param int|string $code
* @param bool $objectData
* @return JsonResponse
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
* @author zbj
* @date 2023/4/12
*/
function success(array $data = [], string $code = Code::SUCCESS, bool $objectData = false): JsonResponse
function success(array $data = [], $code = Code::SUCCESS, bool $objectData = false): JsonResponse
{
if ($objectData) {
$data = (object)$data;
... ...
<?php
namespace App\Http\Controllers\Bside\Product;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Logic\Bside\Product\CategoryLogic;
use App\Http\Requests\Bside\product\CategoryRequest;
use Illuminate\Http\Request;
/**
* Class CategoryController
* @package App\Http\Controllers\Bside
* @author zbj
* @date 2023/4/12
*/
class CategoryController extends BaseController
{
public function index(CategoryLogic $logic)
{
$map = [];
if(!empty($this->param['title'])){
$map[] = ['title', 'like', "%{$this->param['title']}%"];
}
$sort = ['id' => 'desc', 'pid' => "asc"];
$data = $logic->getList($map, $sort);
return $this->success($data);
}
public function info(Request $request, CategoryLogic $logic){
$request->validate([
'id'=>'required'
],[
'id.required' => 'ID不能为空'
]);
$data = $logic->getInfo($this->param['id']);
return $this->success($data);
}
public function save(CategoryRequest $request, CategoryLogic $logic)
{
$data = $logic->save($this->param);
return $this->success($data);
}
public function delete(Request $request, CategoryLogic $logic)
{
$request->validate([
'ids'=>'required'
],[
'ids.required' => 'ID不能为空'
]);
$data = $logic->delete($this->param['ids']);
return $this->success($data);
}
}
... ...
... ... @@ -4,13 +4,20 @@ 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();
... ... @@ -21,7 +28,7 @@ class BaseLogic
* @param array $data
* @return array
*/
public function success(array $data): array
public function success($data = [])
{
return $data;
}
... ... @@ -32,9 +39,238 @@ class BaseLogic
* @param string $message
* @throws BsideGlobalException
*/
public function fail(string $code = Code::SYSTEM_ERROR, $message = "")
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;
}
}
... ...
<?php
namespace App\Http\Logic\Bside\Product;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Product\Category;
class CategoryLogic extends BaseLogic
{
public function __construct()
{
parent::__construct();
$this->model = new Category();
}
}
... ...
<?php
namespace App\Http\Requests\Bside\product;
use App\Enums\Common\Demo;
use BenSampo\Enum\Rules\EnumValue;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\ValidationException;
/**
* Class CategoryRequest
* @package App\Http\Requests\Bside\product
* @author zbj
* @date 2023/4/12
*/
class CategoryRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title'=>'required|max:20',
'image'=>'required',
'keywords'=>'required|max:50',
'describe'=>'required|max:200',
];
}
public function messages()
{
return [
'title.required' => '请输入分类名称',
'title.max' => '分类名称不能超过20个字符',
'image.required' => '请上传分类图片',
'keywords.required' => '请输入分类关键词',
'keywords.max' => '分类关键词不能超过50个字符',
'describe.required' => '请输入分类描述',
'describe.max' => '分类描述不能超过200个字符',
];
}
}
... ...
... ... @@ -9,6 +9,19 @@ class Base extends Model
{
protected $table = '';
public $allCount = 0;
/**
* 日期序列化
* @param \DateTimeInterface $date
* @return string
* @author zbj
* @date 2023/4/13
*/
protected function serializeDate(\DateTimeInterface $date): string
{
return $date->format('Y-m-d H:i:s');
}
/**
* @name 列表数据
* @return void
... ...
... ... @@ -67,7 +67,7 @@ return [
|
*/
'timezone' => 'UTC',
'timezone' => 'PRC',
/*
|--------------------------------------------------------------------------
... ...
... ... @@ -14,4 +14,12 @@ Route::group([], function () {
Route::any('/login', [\App\Http\Controllers\Bside\ComController::class, 'login'])->name('login');
Route::any('/user/lists', [\App\Http\Controllers\Bside\UserController::class, 'lists'])->name('user_lists');
Route::any('/project/page_lists', [\App\Http\Controllers\Bside\ProjectController::class, 'page_lists'])->name('page_lists');
//产品分类
Route::prefix('product')->group(function () {
Route::get('category', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'index'])->name('product_category');
Route::get('category/info', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'info'])->name('product_category_info');
Route::post('category/save', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'save'])->name('product_category_save');
Route::post('category/delete', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'delete'])->name('product_category_delete');
});
});
... ...