作者 赵彬吉

update

@@ -9,6 +9,7 @@ use App\Utils\EncryptUtils; @@ -9,6 +9,7 @@ use App\Utils\EncryptUtils;
9 use App\Utils\LogUtils; 9 use App\Utils\LogUtils;
10 use Illuminate\Database\Eloquent\ModelNotFoundException; 10 use Illuminate\Database\Eloquent\ModelNotFoundException;
11 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; 11 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
  12 +use Illuminate\Support\Arr;
12 use Illuminate\Support\Facades\Route; 13 use Illuminate\Support\Facades\Route;
13 use Illuminate\Validation\ValidationException; 14 use Illuminate\Validation\ValidationException;
14 use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException; 15 use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
@@ -135,6 +136,11 @@ class Handler extends ExceptionHandler @@ -135,6 +136,11 @@ class Handler extends ExceptionHandler
135 //开启debug 错误原样输出 136 //开启debug 错误原样输出
136 $debub = config('app.debug'); 137 $debub = config('app.debug');
137 $message = $debub ? $message : ($code->description ?? $message); 138 $message = $debub ? $message : ($code->description ?? $message);
  139 +
  140 + //请求参数错误 输出具体错误信息
  141 + if($code == Code::USER_PARAMS_ERROE()){
  142 + $message = Arr::first(Arr::first($exception->errors()));
  143 + }
138 $response = [ 144 $response = [
139 'code' => $code, 145 'code' => $code,
140 'message' => $message 146 'message' => $message
  1 +<?php
  2 +
  3 +namespace App\Helper;
  4 +
  5 +
  6 +/**
  7 + * 验证
  8 + */
  9 +class Arrays
  10 +{
  11 + /**
  12 + * 把返回的数据集转换成Tree
  13 + * @param $list
  14 + * @param string $pk
  15 + * @param string $pid
  16 + * @param string $child
  17 + * @param int $root
  18 + * @return array
  19 + * @author zbj
  20 + * @date 2023/4/13
  21 + */
  22 + public static function listToTree($list, $pk = 'id', $pid = 'pid', $child = 'children', $root = 0)
  23 + {
  24 + // 创建Tree
  25 + $tree = array();
  26 + if (is_array($list)) {
  27 + // 创建基于主键的数组引用
  28 + $refer = array();
  29 + foreach ($list as $key => $data) {
  30 + $refer[$data[$pk]] = &$list[$key];
  31 + }
  32 + foreach ($list as $key => $data) {
  33 + // 判断是否存在parent
  34 + $parentId = $data[$pid];
  35 + if ($root == $parentId) {
  36 + $tree[] = &$list[$key];
  37 + } else {
  38 + if (isset($refer[$parentId])) {
  39 + $parent = &$refer[$parentId];
  40 + $parent[$child][] = &$list[$key];
  41 + }
  42 + }
  43 + }
  44 + }
  45 + return $tree;
  46 + }
  47 +
  48 +
  49 + /**
  50 + * 分隔字符串成数组并按照指定的函数过滤数组
  51 + * @param $string
  52 + * @param string $filters
  53 + * @param string $delimiter
  54 + * @return array|false|string[]
  55 + * @author zbj
  56 + * @date 2023/4/13
  57 + */
  58 + public static function splitFilterToArray($string, $filters = 'trim', $delimiter = ',')
  59 + {
  60 + if (!$string) {
  61 + return [];
  62 + }
  63 + $data = !is_array($string) ? explode($delimiter, $string) : $string;
  64 + $filters = explode(',', $filters);
  65 + if (!$filters) {//没有值或者没有过滤函数
  66 + return $data;
  67 + }
  68 + //过滤
  69 + foreach ($filters as $fun) {
  70 + if (!function_exists($fun)) {
  71 + continue;
  72 + }
  73 + $data = array_map($fun, $data);
  74 + }
  75 +
  76 + return $data;
  77 + }
  78 +}
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Bside; @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Bside;
5 use App\Enums\Common\Code; 5 use App\Enums\Common\Code;
6 use App\Http\Controllers\Controller; 6 use App\Http\Controllers\Controller;
7 use App\Utils\EncryptUtils; 7 use App\Utils\EncryptUtils;
  8 +use Illuminate\Http\JsonResponse;
8 use \Illuminate\Http\Request; 9 use \Illuminate\Http\Request;
9 use Illuminate\Http\Response; 10 use Illuminate\Http\Response;
10 use Illuminate\Http\Exceptions\HttpResponseException; 11 use Illuminate\Http\Exceptions\HttpResponseException;
@@ -51,13 +52,13 @@ class BaseController extends Controller @@ -51,13 +52,13 @@ class BaseController extends Controller
51 /** 52 /**
52 * 成功返回 53 * 成功返回
53 * @param array $data 54 * @param array $data
54 - * @param string $code 55 + * @param int|string $code
55 * @param bool $objectData 56 * @param bool $objectData
56 * @return JsonResponse 57 * @return JsonResponse
57 - * @throws \Psr\Container\ContainerExceptionInterface  
58 - * @throws \Psr\Container\NotFoundExceptionInterface 58 + * @author zbj
  59 + * @date 2023/4/12
59 */ 60 */
60 - function success(array $data = [], string $code = Code::SUCCESS, bool $objectData = false): JsonResponse 61 + function success(array $data = [], $code = Code::SUCCESS, bool $objectData = false): JsonResponse
61 { 62 {
62 if ($objectData) { 63 if ($objectData) {
63 $data = (object)$data; 64 $data = (object)$data;
  1 +<?php
  2 +
  3 +namespace App\Http\Controllers\Bside\Product;
  4 +
  5 +use App\Http\Controllers\Bside\BaseController;
  6 +use App\Http\Logic\Bside\Product\CategoryLogic;
  7 +use App\Http\Requests\Bside\product\CategoryRequest;
  8 +use Illuminate\Http\Request;
  9 +
  10 +/**
  11 + * Class CategoryController
  12 + * @package App\Http\Controllers\Bside
  13 + * @author zbj
  14 + * @date 2023/4/12
  15 + */
  16 +class CategoryController extends BaseController
  17 +{
  18 +
  19 + public function index(CategoryLogic $logic)
  20 + {
  21 + $map = [];
  22 + if(!empty($this->param['title'])){
  23 + $map[] = ['title', 'like', "%{$this->param['title']}%"];
  24 + }
  25 + $sort = ['id' => 'desc', 'pid' => "asc"];
  26 + $data = $logic->getList($map, $sort);
  27 + return $this->success($data);
  28 + }
  29 +
  30 + public function info(Request $request, CategoryLogic $logic){
  31 + $request->validate([
  32 + 'id'=>'required'
  33 + ],[
  34 + 'id.required' => 'ID不能为空'
  35 + ]);
  36 + $data = $logic->getInfo($this->param['id']);
  37 + return $this->success($data);
  38 + }
  39 +
  40 + public function save(CategoryRequest $request, CategoryLogic $logic)
  41 + {
  42 + $data = $logic->save($this->param);
  43 + return $this->success($data);
  44 + }
  45 +
  46 + public function delete(Request $request, CategoryLogic $logic)
  47 + {
  48 + $request->validate([
  49 + 'ids'=>'required'
  50 + ],[
  51 + 'ids.required' => 'ID不能为空'
  52 + ]);
  53 +
  54 + $data = $logic->delete($this->param['ids']);
  55 + return $this->success($data);
  56 + }
  57 +}
@@ -4,13 +4,20 @@ namespace App\Http\Logic\Bside; @@ -4,13 +4,20 @@ namespace App\Http\Logic\Bside;
4 4
5 use App\Enums\Common\Code; 5 use App\Enums\Common\Code;
6 use App\Exceptions\BsideGlobalException; 6 use App\Exceptions\BsideGlobalException;
  7 +use App\Helper\Arrays;
  8 +use Illuminate\Support\Facades\Cache;
7 9
8 /** 10 /**
9 * @notes: 逻辑层基类 控制器调用 统一返回 统一抛出异常 11 * @notes: 逻辑层基类 控制器调用 统一返回 统一抛出异常
10 */ 12 */
11 class BaseLogic 13 class BaseLogic
12 { 14 {
  15 + protected $model;
  16 +
13 protected $requestAll; 17 protected $requestAll;
  18 +
  19 + protected $is_cache = true; //是否缓存数据
  20 +
14 public function __construct() 21 public function __construct()
15 { 22 {
16 $this->requestAll = request()->all(); 23 $this->requestAll = request()->all();
@@ -21,7 +28,7 @@ class BaseLogic @@ -21,7 +28,7 @@ class BaseLogic
21 * @param array $data 28 * @param array $data
22 * @return array 29 * @return array
23 */ 30 */
24 - public function success(array $data): array 31 + public function success($data = [])
25 { 32 {
26 return $data; 33 return $data;
27 } 34 }
@@ -32,9 +39,238 @@ class BaseLogic @@ -32,9 +39,238 @@ class BaseLogic
32 * @param string $message 39 * @param string $message
33 * @throws BsideGlobalException 40 * @throws BsideGlobalException
34 */ 41 */
35 - public function fail(string $code = Code::SYSTEM_ERROR, $message = "") 42 + public function fail($message = "", string $code = Code::SYSTEM_ERROR)
36 { 43 {
37 throw new BsideGlobalException($code, $message); 44 throw new BsideGlobalException($code, $message);
38 } 45 }
39 46
  47 +
  48 + /**
  49 + * 列表
  50 + * @param array $map
  51 + * @param array $sort
  52 + * @param int $limit
  53 + * @return array
  54 + * @author zbj
  55 + * @date 2023/4/13
  56 + */
  57 + public function getList($map = [], $sort = ['id' => 'desc'], $limit = 20)
  58 + {
  59 + // 闭包查询条件格式化
  60 + $query = $this->formatQuery($map);
  61 +
  62 + // 排序(支持多重排序)
  63 + $query = $query->when($sort, function ($query, $sort) {
  64 + foreach ($sort as $k=>$v) {
  65 + $query->orderBy($k, $v);
  66 + }
  67 + });
  68 +
  69 + // 数据分页设置
  70 + if ($limit) {
  71 + $result = $query->simplePaginate();
  72 + }else{
  73 + $result = $query->get();
  74 + }
  75 +
  76 + return $this->success($result ? $result->toArray() : []);
  77 + }
  78 +
  79 +
  80 + /**
  81 + * 详情
  82 + * @param $id
  83 + * @return
  84 + * @author zbj
  85 + * @date 2023/4/13
  86 + */
  87 + public function getInfo($id)
  88 + {
  89 + if($this->is_cache){
  90 + $info = Cache::get($this->getInfoCacheKey($id));
  91 + if (!$info) {
  92 + $info = $this->model->find($id);
  93 + if($info){
  94 + Cache::put($this->getInfoCacheKey($id), $info);
  95 + }
  96 + }
  97 + }else{
  98 + $info = $this->model->find($id);
  99 + }
  100 + return $this->success($info->toArray());
  101 + }
  102 +
  103 + /**
  104 + * 保存
  105 + * @param $param
  106 + * @return array
  107 + * @throws BsideGlobalException
  108 + * @author zbj
  109 + * @date 2023/4/13
  110 + */
  111 + public function save($param){
  112 + if(empty($param['id'])){
  113 + $param['created_at'] = $param['updated_at'] = date('Y-m-d H:i:s');
  114 + $res = $this->model->insert($param);
  115 + }else{
  116 + $info = $this->getInfo($param['id']);
  117 + if(!$info){
  118 + $this->fail('数据不存在或者已经删除');
  119 + }
  120 + $param['updated_at'] = date('Y-m-d H:i:s');
  121 + $res = $this->model->where('id', $param['id'])->update($param);
  122 + }
  123 + if($res){
  124 + //清缓存
  125 + if($this->is_cache && !empty($param['id'])){
  126 + Cache::forget($this->getInfoCacheKey($param['id']));
  127 + }
  128 + return $this->success();
  129 + }else{
  130 + $this->fail('保存失败');
  131 + }
  132 + }
  133 +
  134 + /**
  135 + * 批量删除
  136 + * @param $ids
  137 + * @return array
  138 + * @throws BsideGlobalException
  139 + * @author zbj
  140 + * @date 2023/4/13
  141 + */
  142 + public function delete($ids){
  143 + $ids = array_filter(Arrays::splitFilterToArray($ids), 'intval');
  144 + if(!$ids){
  145 + $this->fail('ID不能为空');
  146 + }
  147 + $map[] = ['id', 'in', $ids];
  148 + $res = $this->formatQuery($map)->delete();
  149 + if($res){
  150 + if($this->is_cache && !empty($param['id'])){
  151 + Cache::forget($this->getInfoCacheKey($param['id']));
  152 + }
  153 + return $this->success();
  154 + }else{
  155 + $this->fail('删除失败');
  156 + }
  157 + }
  158 +
  159 + /**
  160 + * @param $id
  161 + * @return string
  162 + * @author zbj
  163 + * @date 2023/4/13
  164 + */
  165 + public function getInfoCacheKey($id){
  166 + return $this->model->getTable() . '_info_' . $id;
  167 + }
  168 +
  169 + /**
  170 + * 格式化查询条件
  171 + * @param $map
  172 + * @return mixed
  173 + * @author zbj
  174 + * @date 2023/4/13
  175 + */
  176 + public function formatQuery($map, $model = '')
  177 + {
  178 + $model = $model ?: $this->model;
  179 + $query = $model->where(function ($query) use ($map) {
  180 + foreach ($map as $v) {
  181 + if ($v instanceof \Closure) {
  182 + $query = $query->where($v);
  183 + continue;
  184 + }
  185 + // 判断是否是键值对类型
  186 + if (key($v) !== 0) {
  187 + $key = key($v);
  188 + $val = $v[$key];
  189 + $v = [$key, is_array($val) ? 'in' : '=', $val];
  190 + }
  191 + switch ($v[1]) {
  192 + case 'like':
  193 + // like查询 ['name|title', 'like', '%a%']
  194 + if (strpos($v[0], '|') !== false) {
  195 + $query->where(function ($query) use ($v) {
  196 + $item = explode('|', $v[0]);
  197 + foreach ($item as $vo) {
  198 + $query->orWhere($vo, $v[1], $v[2]);
  199 + }
  200 + });
  201 + } else {
  202 + $query->where($v[0], $v[1], $v[2]);
  203 + }
  204 + break;
  205 + case 'in':
  206 + // in查询 ['id', 'in', [1,2,3]]
  207 + if (!is_array($v[2])) {
  208 + $v[2] = explode(',', $v[2]);
  209 + }
  210 + $query->whereIn($v[0], $v[2]);
  211 + break;
  212 + case 'not in':
  213 + // not in查询 ['id', 'not in', [1,2,3]]
  214 + if (!is_array($v[2])) {
  215 + $v[2] = explode(',', $v[2]);
  216 + }
  217 + $query->whereNotIn($v[0], $v[2]);
  218 + break;
  219 + case 'between':
  220 + // between查询 ['created_at', 'between', ['xxx', 'xxx]]
  221 + if (!is_array($v[2])) {
  222 + $v[2] = explode(',', $v[2]);
  223 + }
  224 + $query->whereBetween($v[0], $v[2]);
  225 + break;
  226 + case 'not between':
  227 + // not between查询 ['created_at', 'not between', ['xxx', 'xxx]]
  228 + if (!is_array($v[2])) {
  229 + $v[2] = explode(',', $v[2]);
  230 + }
  231 + $query->whereNotBetween($v[0], $v[2]);
  232 + break;
  233 + case 'null':
  234 + // null查询 ['deleted_at', 'null']
  235 + $query->whereNull($v[0]);
  236 + break;
  237 + case "not null":
  238 + // not null查询 ['deleted_at', 'not null']
  239 + $query->whereNotNull($v[0]);
  240 + break;
  241 + case "or":
  242 + // or查询 [[['status'=>1],['status'=>2]], 'or'];
  243 + //格式:or (status=1 and status=2)
  244 + $where = $v[0];
  245 + $query->orWhere(function ($query) use ($where) {
  246 + // 递归解析查询条件
  247 + $this->formatQuery($where, $query);
  248 + });
  249 + break;
  250 + case 'xor':
  251 + // xor查询 [[['status'=>1],['status'=>2]], 'xor'];
  252 + // 格式:and (status=1 or status=2)
  253 + $where = $v[0];
  254 + $query->where(function ($query) use ($where) {
  255 + foreach ($where as $w) {
  256 + $query->orWhere(function ($query) use ($w) {
  257 + // 递归解析查询条件
  258 + $this->formatQuery([$w], $query);
  259 + });
  260 + }
  261 + });
  262 + break;
  263 + default:
  264 + // 常规查询
  265 + if (count($v) == 2) {
  266 + $query->where($v[0], '=', $v[1]);
  267 + } else {
  268 + $query->where($v[0], $v[1], $v[2]);
  269 + }
  270 + break;
  271 + }
  272 + }
  273 + });
  274 + return $query;
  275 + }
40 } 276 }
  1 +<?php
  2 +
  3 +namespace App\Http\Logic\Bside\Product;
  4 +
  5 +use App\Http\Logic\Bside\BaseLogic;
  6 +use App\Models\Product\Category;
  7 +
  8 +class CategoryLogic extends BaseLogic
  9 +{
  10 + public function __construct()
  11 + {
  12 + parent::__construct();
  13 +
  14 + $this->model = new Category();
  15 + }
  16 +}
  1 +<?php
  2 +
  3 +namespace App\Http\Requests\Bside\product;
  4 +
  5 +use App\Enums\Common\Demo;
  6 +use BenSampo\Enum\Rules\EnumValue;
  7 +use Illuminate\Contracts\Validation\Validator;
  8 +use Illuminate\Foundation\Http\FormRequest;
  9 +use Illuminate\Validation\ValidationException;
  10 +
  11 +/**
  12 + * Class CategoryRequest
  13 + * @package App\Http\Requests\Bside\product
  14 + * @author zbj
  15 + * @date 2023/4/12
  16 + */
  17 +class CategoryRequest extends FormRequest
  18 +{
  19 + /**
  20 + * Determine if the user is authorized to make this request.
  21 + *
  22 + * @return bool
  23 + */
  24 + public function authorize()
  25 + {
  26 + return true;
  27 + }
  28 +
  29 + /**
  30 + * Get the validation rules that apply to the request.
  31 + *
  32 + * @return array
  33 + */
  34 + public function rules()
  35 + {
  36 + return [
  37 + 'title'=>'required|max:20',
  38 + 'image'=>'required',
  39 + 'keywords'=>'required|max:50',
  40 + 'describe'=>'required|max:200',
  41 + ];
  42 + }
  43 +
  44 + public function messages()
  45 + {
  46 + return [
  47 + 'title.required' => '请输入分类名称',
  48 + 'title.max' => '分类名称不能超过20个字符',
  49 + 'image.required' => '请上传分类图片',
  50 + 'keywords.required' => '请输入分类关键词',
  51 + 'keywords.max' => '分类关键词不能超过50个字符',
  52 + 'describe.required' => '请输入分类描述',
  53 + 'describe.max' => '分类描述不能超过200个字符',
  54 + ];
  55 + }
  56 +
  57 +}
@@ -9,6 +9,19 @@ class Base extends Model @@ -9,6 +9,19 @@ class Base extends Model
9 { 9 {
10 protected $table = ''; 10 protected $table = '';
11 public $allCount = 0; 11 public $allCount = 0;
  12 +
  13 + /**
  14 + * 日期序列化
  15 + * @param \DateTimeInterface $date
  16 + * @return string
  17 + * @author zbj
  18 + * @date 2023/4/13
  19 + */
  20 + protected function serializeDate(\DateTimeInterface $date): string
  21 + {
  22 + return $date->format('Y-m-d H:i:s');
  23 + }
  24 +
12 /** 25 /**
13 * @name 列表数据 26 * @name 列表数据
14 * @return void 27 * @return void
@@ -67,7 +67,7 @@ return [ @@ -67,7 +67,7 @@ return [
67 | 67 |
68 */ 68 */
69 69
70 - 'timezone' => 'UTC', 70 + 'timezone' => 'PRC',
71 71
72 /* 72 /*
73 |-------------------------------------------------------------------------- 73 |--------------------------------------------------------------------------
@@ -14,4 +14,12 @@ Route::group([], function () { @@ -14,4 +14,12 @@ Route::group([], function () {
14 Route::any('/login', [\App\Http\Controllers\Bside\ComController::class, 'login'])->name('login'); 14 Route::any('/login', [\App\Http\Controllers\Bside\ComController::class, 'login'])->name('login');
15 Route::any('/user/lists', [\App\Http\Controllers\Bside\UserController::class, 'lists'])->name('user_lists'); 15 Route::any('/user/lists', [\App\Http\Controllers\Bside\UserController::class, 'lists'])->name('user_lists');
16 Route::any('/project/page_lists', [\App\Http\Controllers\Bside\ProjectController::class, 'page_lists'])->name('page_lists'); 16 Route::any('/project/page_lists', [\App\Http\Controllers\Bside\ProjectController::class, 'page_lists'])->name('page_lists');
  17 +
  18 + //产品分类
  19 + Route::prefix('product')->group(function () {
  20 + Route::get('category', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'index'])->name('product_category');
  21 + Route::get('category/info', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'info'])->name('product_category_info');
  22 + Route::post('category/save', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'save'])->name('product_category_save');
  23 + Route::post('category/delete', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'delete'])->name('product_category_delete');
  24 + });
17 }); 25 });