作者 liyuhang

Merge branch 'dev' of http://47.244.231.31:8099/zhl/globalso-v6 into dev

@@ -3,6 +3,9 @@ @@ -3,6 +3,9 @@
3 namespace App\Exceptions; 3 namespace App\Exceptions;
4 4
5 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; 5 use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
  6 +
  7 +use Illuminate\Support\Arr;
  8 +
6 use Throwable; 9 use Throwable;
7 10
8 class Handler extends ExceptionHandler 11 class Handler extends ExceptionHandler
  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 +}
@@ -4,8 +4,8 @@ namespace App\Http\Controllers\Bside; @@ -4,8 +4,8 @@ namespace App\Http\Controllers\Bside;
4 4
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 \Illuminate\Http\Request;  
8 -use Illuminate\Http\Response; 7 +use Illuminate\Http\JsonResponse;
  8 +use Illuminate\Http\Request;
9 use Illuminate\Http\Exceptions\HttpResponseException; 9 use Illuminate\Http\Exceptions\HttpResponseException;
10 use Illuminate\Support\Facades\Cache; 10 use Illuminate\Support\Facades\Cache;
11 11
@@ -45,6 +45,28 @@ class BaseController extends Controller @@ -45,6 +45,28 @@ class BaseController extends Controller
45 $this->user = $info; 45 $this->user = $info;
46 $this->uid = $info['id']; 46 $this->uid = $info['id'];
47 } 47 }
  48 + /**
  49 + * 成功返回
  50 + * @param array $data
  51 + * @param int|string $code
  52 + * @param bool $objectData
  53 + * @return JsonResponse
  54 + * @author zbj
  55 + * @date 2023/4/12
  56 + */
  57 + function success(array $data = [], $code = Code::SUCCESS, bool $objectData = false): JsonResponse
  58 + {
  59 + if ($objectData) {
  60 + $data = (object)$data;
  61 + }
  62 + $code = Code::fromValue($code);
  63 + $response = [
  64 + 'code' => $code->value,
  65 + 'data' => $data,
  66 + 'msg' => $code->description,
  67 + ];
  68 + return response()->json($response,200,$this->header);
  69 + }
48 70
49 /** 71 /**
50 * @name 参数过滤 72 * @name 参数过滤
  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 +
  27 + $data = $logic->getList($map, $sort);
  28 + return $this->success($data);
  29 + }
  30 +
  31 + public function info(Request $request, CategoryLogic $logic){
  32 + $request->validate([
  33 + 'id'=>'required'
  34 + ],[
  35 + 'id.required' => 'ID不能为空'
  36 + ]);
  37 + $data = $logic->getInfo($this->param['id']);
  38 + return $this->success($data);
  39 + }
  40 +
  41 + public function save(CategoryRequest $request, CategoryLogic $logic)
  42 + {
  43 + $data = $logic->save($this->param);
  44 + return $this->success($data);
  45 + }
  46 +
  47 + public function delete(Request $request, CategoryLogic $logic)
  48 + {
  49 + $request->validate([
  50 + 'ids'=>'required'
  51 + ],[
  52 + 'ids.required' => 'ID不能为空'
  53 + ]);
  54 +
  55 + $data = $logic->delete($this->param['ids']);
  56 + return $this->success($data);
  57 + }
  58 +}
@@ -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 +}
@@ -16,6 +16,19 @@ class Base extends Model @@ -16,6 +16,19 @@ class Base extends Model
16 'created_at' => 'datetime:Y-m-d H:i:s', 16 'created_at' => 'datetime:Y-m-d H:i:s',
17 'updated_at' => 'datetime:Y-m-d H:i:s', 17 'updated_at' => 'datetime:Y-m-d H:i:s',
18 ]; 18 ];
  19 +
  20 + /**
  21 + * 日期序列化
  22 + * @param \DateTimeInterface $date
  23 + * @return string
  24 + * @author zbj
  25 + * @date 2023/4/13
  26 + */
  27 + protected function serializeDate(\DateTimeInterface $date): string
  28 + {
  29 + return $date->format('Y-m-d H:i:s');
  30 + }
  31 +
19 /** 32 /**
20 * @name 列表数据 33 * @name 列表数据
21 * @return void 34 * @return void
1 -<?php  
2 -  
3 -namespace App\Models;  
4 -  
5 -class Product extends Base  
6 -{  
7 - //设置关联表名  
8 - protected $table = 'gl_product';  
9 - //自动维护create_at创建时间 updated_at修改时间  
10 - public $timestamps = true;  
11 -  
12 -}  
  1 +<?php
  2 +
  3 +namespace App\Models\Product;
  4 +
  5 +use App\Models\Base;
  6 +
  7 +class Category extends Base
  8 +{
  9 + //设置关联表名
  10 + protected $table = 'gl_product_category';
  11 +
  12 +}
@@ -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 |--------------------------------------------------------------------------
@@ -27,4 +27,12 @@ Route::group([], function () { @@ -27,4 +27,12 @@ Route::group([], function () {
27 Route::any('/project_role/edit', [\App\Http\Controllers\Bside\ProjectRoleController::class, 'edit'])->name('project_role_edit'); 27 Route::any('/project_role/edit', [\App\Http\Controllers\Bside\ProjectRoleController::class, 'edit'])->name('project_role_edit');
28 Route::any('/project_role/status', [\App\Http\Controllers\Bside\ProjectRoleController::class, 'status'])->name('project_role_status'); 28 Route::any('/project_role/status', [\App\Http\Controllers\Bside\ProjectRoleController::class, 'status'])->name('project_role_status');
29 Route::any('/project_role/del', [\App\Http\Controllers\Bside\ProjectRoleController::class, 'del'])->name('project_role_del'); 29 Route::any('/project_role/del', [\App\Http\Controllers\Bside\ProjectRoleController::class, 'del'])->name('project_role_del');
  30 +
  31 + //产品分类
  32 + Route::prefix('product')->group(function () {
  33 + Route::get('category', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'index'])->name('product_category');
  34 + Route::get('category/info', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'info'])->name('product_category_info');
  35 + Route::post('category/save', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'save'])->name('product_category_save');
  36 + Route::post('category/delete', [\App\Http\Controllers\Bside\Product\CategoryController::class, 'delete'])->name('product_category_delete');
  37 + });
30 }); 38 });