作者 邓超

导航栏 nav

@@ -88,3 +88,71 @@ if(!function_exists('_get_child')){ @@ -88,3 +88,71 @@ if(!function_exists('_get_child')){
88 return $new_arr ? $new_arr : false; 88 return $new_arr ? $new_arr : false;
89 } 89 }
90 } 90 }
  91 +
  92 +
  93 +
  94 +/**
  95 + * 把返回的数据集转换成Tree
  96 + * @param $list array 数据列表
  97 + * @param string|int $pk 主键|root
  98 + * @param string $pid 父id
  99 + * @param string $child 子键
  100 + * @param int $root 获取哪个id下面
  101 + * @param bool $empty_child 当子数据不存在,是否要返回空子数据
  102 + * @return array
  103 + */
  104 +function list_to_tree($list, $pk='id',$pid = 'pid',$child = '_child',$root=0,$empty_child=true) {
  105 + // 如果是数字,则是root
  106 + if(is_numeric($pk)){
  107 + $root = $pk;
  108 + $pk = 'id';
  109 + }
  110 + // 创建Tree
  111 + $tree = array();
  112 + if(is_array($list)) {
  113 + // 创建基于主键的数组引用
  114 + $refer = array();
  115 + foreach ($list as $key => $data) {
  116 + if($empty_child){
  117 + $list[$key][$child] = [];
  118 + }
  119 + $refer[$data[$pk]] =& $list[$key];
  120 + }
  121 + foreach ($list as $key => $data) {
  122 + // 判断是否存在parent
  123 + $parentId = $data[$pid];
  124 + if ($root == $parentId) {
  125 + $tree[] =& $list[$key];
  126 + }else{
  127 + if (isset($refer[$parentId])) {
  128 + $refer[$parentId][$child][] = & $list[$key];
  129 + }
  130 + }
  131 + }
  132 + }
  133 + return $tree;
  134 +}
  135 +
  136 +/**
  137 + * tree数据转list
  138 + * @param $tree
  139 + * @param string $child
  140 + * @return array
  141 + * @author:dc
  142 + * @time 2022/1/11 10:13
  143 + */
  144 +function tree_to_list($tree, $child='_child'){
  145 + $lists = [];
  146 + foreach ($tree as $item){
  147 + $c = $item[$child]??[];
  148 + unset($item[$child]);
  149 + $lists[] = $item;
  150 + if ($c){
  151 + $lists = array_merge($lists,tree_to_list($c, $child));
  152 + }
  153 + }
  154 + return $lists;
  155 +}
  156 +
  157 +
  158 +
  1 +<?php
  2 +
  3 +namespace App\Http\Controllers\Bside;
  4 +
  5 +
  6 +use App\Enums\Common\Code;
  7 +use App\Models\BNav;
  8 +
  9 +/**
  10 + * 导航栏目 b端编辑 c端显示
  11 + * @author:dc
  12 + * @time 2023/5/8 16:31
  13 + * Class NavController
  14 + * @package App\Http\Controllers\Bside
  15 + */
  16 +class NavController extends BaseController
  17 +{
  18 +
  19 + /**
  20 + * 验证规则
  21 + * @var array[]
  22 + */
  23 + private $verify = [
  24 + 'role' => [
  25 + 'pid' => ['required','integer','gte:0'],
  26 + 'name' => ['required','max:100'],
  27 + 'location' => ['required','in:header,footer'],
  28 + 'url' => ['required','max:200'],
  29 + 'status' => ['required','in:0,1'],
  30 + 'target' => ['required','in:0,1'],
  31 + 'sort' => ['required','integer','gte:0']
  32 + ],
  33 + 'message' => [
  34 + 'pid.required' => '上级选择错误',
  35 + 'pid.gte' => '上级选择错误',
  36 + 'pid.integer' => '上级选择错误',
  37 + 'name.required' => '名称必须',
  38 + 'name.max' => '名称不能超过100个字符',
  39 + 'location.required' => '位置选择错误',
  40 + 'location.in' => '位置选择错误',
  41 + 'url.required' => '链接必须',
  42 + 'url.max' => '链接不能超过200个字符',
  43 + 'status.required' => '状态选择错误',
  44 + 'status.in' => '状态必须是显示/隐藏',
  45 + 'target.required' => '打开方式必须',
  46 + 'target.in' => '打开方式选择错误',
  47 + 'sort.required' => '排序必须',
  48 + 'sort.integer' => '排序必须是一个数字',
  49 + 'sort.gte' => '排序必须大于等于0',
  50 + ],
  51 + 'attr' => [
  52 +
  53 + ]
  54 + ];
  55 +
  56 + /**
  57 + * 列表数据
  58 + * @throws \Psr\Container\ContainerExceptionInterface
  59 + * @throws \Psr\Container\NotFoundExceptionInterface
  60 + * @author:dc
  61 + * @time 2023/5/8 16:37
  62 + */
  63 + public function index(){
  64 +
  65 + $isTree = $this->param['tree']??false;
  66 +
  67 + $lists = BNav::_all($this->user['project_id'])->toArray();
  68 +
  69 + if($isTree){
  70 + $lists = list_to_tree($lists);
  71 + }
  72 +
  73 + return $this->success($lists);
  74 +
  75 + }
  76 +
  77 +
  78 +
  79 + /**
  80 + * 创建导航栏
  81 + * @author:dc
  82 + * @time 2023/5/8 16:39
  83 + */
  84 + public function create(){
  85 + return $this->save();
  86 + }
  87 +
  88 +
  89 + /**
  90 + * 修改
  91 + * @return \Illuminate\Http\JsonResponse
  92 + * @throws \Illuminate\Validation\ValidationException
  93 + * @throws \Psr\Container\ContainerExceptionInterface
  94 + * @throws \Psr\Container\NotFoundExceptionInterface
  95 + * @author:dc
  96 + * @time 2023/5/8 17:06
  97 + */
  98 + public function update(){
  99 + $this->verify['role']['id'] = ['required','integer','gt:0'];
  100 + $this->verify['message']['id.gt'] = $this->verify['message']['id.integer'] = $this->verify['message']['id.required'] = '编辑导航数据不存在';
  101 + return $this->save();
  102 + }
  103 +
  104 + /**
  105 + * 新增修改
  106 + * @return \Illuminate\Http\JsonResponse
  107 + * @throws \Illuminate\Validation\ValidationException
  108 + * @throws \Psr\Container\ContainerExceptionInterface
  109 + * @throws \Psr\Container\NotFoundExceptionInterface
  110 + * @author:dc
  111 + * @time 2023/5/8 17:06
  112 + */
  113 + private function save(){
  114 + $data = $this->validate(request() ,$this->verify['role'],$this->verify['message']);
  115 +
  116 + if($data['pid']){
  117 + // 验证是否存在上级
  118 + $all = BNav::_all($this->user['project_id'],$data['location']);
  119 + if(!$all->where('id',$data['pid'])->count()){
  120 + return $this->response('上级栏目不存在','B_NAV_PID_NOTFOUND');
  121 + }
  122 + // 上级不允许是自己的下级
  123 + if(!empty($data['id'])){
  124 + $all = list_to_tree($all->toArray(),$data['id']);
  125 + $all = tree_to_list($all);
  126 + if(in_array($data['pid'],array_column($all,'id'))){
  127 + return $this->response('上级栏目不允许为本身的下级','B_NAV_PID_IS_CHILD');
  128 + }
  129 + }
  130 + }
  131 +
  132 + // 保存
  133 + $id = BNav::_save($this->user['project_id'],$data,$data['id']??0);
  134 +
  135 + if($id===-1){
  136 + return $this->response('导航数据不存在','B_NAV_NOTFOUND');
  137 + }
  138 +
  139 + return $this->success(BNav::_find($this->user['project_id'],$id,true));
  140 + }
  141 +
  142 +
  143 +
  144 +
  145 + public function delete(){
  146 +
  147 + }
  148 +
  149 +
  150 +
  151 +
  152 +
  153 +
  154 +
  155 +
  156 +}
@@ -7,6 +7,7 @@ use App\Exceptions\BsideGlobalException; @@ -7,6 +7,7 @@ use App\Exceptions\BsideGlobalException;
7 use App\Models\Template\AHeadFoot; 7 use App\Models\Template\AHeadFoot;
8 use App\Models\Template\BCustom; 8 use App\Models\Template\BCustom;
9 use App\Models\Template\BHeadFoot; 9 use App\Models\Template\BHeadFoot;
  10 +use App\Models\Template\BTemplate;
10 use Illuminate\Support\Facades\DB; 11 use Illuminate\Support\Facades\DB;
11 12
12 /** 13 /**
@@ -30,16 +31,13 @@ class TemplateController extends BaseController @@ -30,16 +31,13 @@ class TemplateController extends BaseController
30 */ 31 */
31 public function index(){ 32 public function index(){
32 33
33 - $data = BHeadFoot::_get($this->user['project_id']); 34 + $data = BTemplate::_get($this->user['project_id']);
34 35
35 // todo::这里要进行html的替换 36 // todo::这里要进行html的替换
36 37
37 38
38 39
39 - return $this->success([  
40 - 'header' => $data[BHeadFoot::TYPE_HEADER]??'',  
41 - 'footer' => $data[BHeadFoot::TYPE_FOOTER]??'',  
42 - ]); 40 + return $this->success($data);
43 } 41 }
44 42
45 43
  1 +<?php
  2 +
  3 +namespace App\Models;
  4 +
  5 +use Illuminate\Database\Eloquent\SoftDeletes;
  6 +
  7 +/**
  8 + * b端控制, c端显示的导航
  9 + * @author:dc
  10 + * @time 2023/5/8 16:14
  11 + * Class BNav
  12 + * @package App\Models
  13 + */
  14 +class BNav extends Base
  15 +{
  16 +
  17 + protected $table = 'gl_bside_nav';
  18 +
  19 + use SoftDeletes;
  20 +
  21 + public $hidden = ['deleted_at','project_id'];
  22 +
  23 +
  24 + /**
  25 + * 显示
  26 + */
  27 + const STATUS_ACTIVE = 1;
  28 +
  29 + /**
  30 + * 隐藏
  31 + */
  32 + const STATUS_DISABLED = 0;
  33 +
  34 +
  35 + /**
  36 + * 创建或者新增导航栏
  37 + * @param int $project_id
  38 + * @param array $data
  39 + * @param int $id
  40 + * @return int
  41 + * @author:dc
  42 + * @time 2023/5/8 16:24
  43 + */
  44 + public static function _save(int $project_id, array $data, int $id = 0):int {
  45 + if($id){
  46 + $model = static::where('id',$id)->where('project_id', $project_id)->first();
  47 + if(!$model){
  48 + return -1;
  49 + }
  50 + }else{
  51 + $model = new static();
  52 + $model->project_id = $project_id;
  53 +
  54 + }
  55 +
  56 + $model->pid = $data['pid'];
  57 + $model->name = $data['name'];
  58 + $model->location = $data['location'];
  59 + $model->url = $data['url'];
  60 + $model->status = $data['status'];
  61 + $model->target = $data['target'];
  62 + $model->sort = $data['sort'];
  63 + $model->save();
  64 +
  65 + return $model->id;
  66 + }
  67 +
  68 +
  69 + /**
  70 + * 删除
  71 + * @param int $project_id
  72 + * @param int $id
  73 + * @return mixed
  74 + * @author:dc
  75 + * @time 2023/5/8 16:27
  76 + */
  77 + public static function _del(int $project_id, int $id){
  78 + return static::where(['project_id'=>$project_id,'id'=>$id])->delete();
  79 + }
  80 +
  81 +
  82 + /**
  83 + * 查询当前项目下的所有栏目信息
  84 + * @param int $project_id
  85 + * @return mixed
  86 + * @author:dc
  87 + * @time 2023/5/8 16:29
  88 + */
  89 + public static function _all(int $project_id, string $location = null)
  90 + {
  91 + return static::where(function ($query) use ($project_id,$location){
  92 + // 那个公司
  93 + $query->where('project_id',$project_id);
  94 + // 显示位置
  95 + $location && $query->where('location',$location);
  96 + })
  97 + ->orderBy('sort')
  98 + ->get();
  99 + }
  100 +
  101 + /**
  102 + * 查询一条数据
  103 + * @param int $project_id
  104 + * @param int $id
  105 + * @return mixed
  106 + * @author:dc
  107 + * @time 2023/5/8 17:04
  108 + */
  109 + public static function _find(int $project_id, int $id, $array = false)
  110 + {
  111 + $data = static::where(['id'=>$id,'project_id'=>$project_id])->first();
  112 + if($data){
  113 + return $array ? $data->toArray() : $data;
  114 + }
  115 + return [];
  116 + }
  117 +
  118 +
  119 + /**
  120 + * 是否存在
  121 + * @param int $project_id
  122 + * @param int $id
  123 + * @return mixed
  124 + * @author:dc
  125 + * @time 2023/5/8 17:24
  126 + */
  127 + public static function _check(int $project_id, int $id)
  128 + {
  129 + return static::where(['id'=>$id,'project_id'=>$project_id])->count();
  130 + }
  131 +
  132 +}
@@ -3,23 +3,17 @@ @@ -3,23 +3,17 @@
3 namespace App\Models\Template; 3 namespace App\Models\Template;
4 4
5 /** 5 /**
6 - * 头部底部 6 + * 自定义 界面
7 * @author:dc 7 * @author:dc
8 - * @time 2023/5/4 15:52  
9 - * Class AHeadFoot 8 + * @time 2023/5/8 13:52
  9 + * Class BTemplate
10 * @package App\Models\Template 10 * @package App\Models\Template
11 */ 11 */
12 -class BHeadFoot extends \App\Models\Base{ 12 +class BTemplate extends \App\Models\Base{
13 13
14 - protected $table = 'gl_bside_template_header_footer'; 14 + protected $table = 'gl_bside_template_html';
15 15
16 16
17 - const TYPE_HEADER = 'H';  
18 - const TYPE_FOOTER = 'F';  
19 -  
20 -// const STATUS_ACTIVE = 1;  
21 -// const STATUS_DISABLED = 0;  
22 -  
23 17
24 /** 18 /**
25 * @param $project_id 19 * @param $project_id
@@ -28,12 +22,12 @@ class BHeadFoot extends \App\Models\Base{ @@ -28,12 +22,12 @@ class BHeadFoot extends \App\Models\Base{
28 * @time 2023/5/4 16:13 22 * @time 2023/5/4 16:13
29 */ 23 */
30 public static function _get($project_id){ 24 public static function _get($project_id){
31 - return static::where(['project_id'=>$project_id,'is_use'=>1])->get(['html','type'])->pluck('html','type')->toArray(); 25 + return static::where(['project_id'=>$project_id])->get(['html','type'])->pluck('html','type')->toArray();
32 } 26 }
33 27
34 28
35 public static function _all($project_id){ 29 public static function _all($project_id){
36 - return static::where(['project_id'=>$project_id,'is_use'=>1])->get(); 30 + return static::where(['project_id'=>$project_id])->get();
37 } 31 }
38 32
39 33
@@ -46,12 +40,11 @@ class BHeadFoot extends \App\Models\Base{ @@ -46,12 +40,11 @@ class BHeadFoot extends \App\Models\Base{
46 * @time 2023/5/4 17:50 40 * @time 2023/5/4 17:50
47 */ 41 */
48 public static function _save($project_id,$type,$html){ 42 public static function _save($project_id,$type,$html){
49 - $data = static::where(['project_id'=>$project_id,'is_use'=>1])->first(); 43 + $data = static::where(['project_id'=>$project_id,'type'=>$type])->first();
50 if(!$data){ 44 if(!$data){
51 $data = new static(); 45 $data = new static();
52 $data->project_id = $project_id; 46 $data->project_id = $project_id;
53 $data->type = $type; 47 $data->type = $type;
54 - $data->is_use = 1;  
55 } 48 }
56 $data->html = $html; 49 $data->html = $html;
57 50
  1 +#!/usr/bin/env php
  2 +<?php
  3 +
  4 +define('LARAVEL_START', microtime(true));
  5 +
  6 +/*
  7 +|--------------------------------------------------------------------------
  8 +| Register The Auto Loader
  9 +|--------------------------------------------------------------------------
  10 +|
  11 +| Composer provides a convenient, automatically generated class loader
  12 +| for our application. We just need to utilize it! We'll require it
  13 +| into the script here so that we do not have to worry about the
  14 +| loading of any our classes "manually". Feels great to relax.
  15 +|
  16 +*/
  17 +
  18 +require __DIR__.'/vendor/autoload.php';
  19 +
  20 +$app = require_once __DIR__.'/bootstrap/app.php';
  21 +
  22 +/*
  23 +|--------------------------------------------------------------------------
  24 +| Run The Artisan Application
  25 +|--------------------------------------------------------------------------
  26 +|
  27 +| When we run the console application, the current CLI command will be
  28 +| executed in this console and the response sent back to a terminal
  29 +| or another output device for the developers. Here goes nothing!
  30 +|
  31 +*/
  32 +
  33 +$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
  34 +
  35 +$status = $kernel->handle(
  36 + $input = new Symfony\Component\Console\Input\ArgvInput,
  37 + new Symfony\Component\Console\Output\ConsoleOutput
  38 +);
  39 +
  40 +/*
  41 +|--------------------------------------------------------------------------
  42 +| Shutdown The Application
  43 +|--------------------------------------------------------------------------
  44 +|
  45 +| Once Artisan has finished running, we will fire off the shutdown events
  46 +| so that any final work may be done by the application before we shut
  47 +| down the process. This is the last thing to happen to the request.
  48 +|
  49 +*/
  50 +
  51 +$kernel->terminate($input, $status);
  52 +
  53 +exit($status);
@@ -171,6 +171,14 @@ Route::middleware(['bloginauth'])->group(function () { @@ -171,6 +171,14 @@ Route::middleware(['bloginauth'])->group(function () {
171 Route::get('/custom', [\App\Http\Controllers\Bside\TemplateController::class, 'custom'])->name('template_custom'); 171 Route::get('/custom', [\App\Http\Controllers\Bside\TemplateController::class, 'custom'])->name('template_custom');
172 }); 172 });
173 173
  174 + // 导航栏编辑
  175 + Route::prefix('nav')->group(function () {
  176 + Route::get('/', [\App\Http\Controllers\Bside\NavController::class, 'index'])->name('bside_nav');
  177 + Route::post('/create', [\App\Http\Controllers\Bside\NavController::class, 'create'])->name('bside_nav_create');
  178 + Route::post('/update', [\App\Http\Controllers\Bside\NavController::class, 'update'])->name('bside_nav_update');
  179 + Route::get('/delete', [\App\Http\Controllers\Bside\NavController::class, 'delete'])->name('bside_nav_delete');
  180 + });
  181 +
174 182
175 183
176 184