diff --git a/app/Http/Controllers/BatchExportController.php b/app/Http/Controllers/BatchExportController.php index c7091974..411c9129 100644 --- a/app/Http/Controllers/BatchExportController.php +++ b/app/Http/Controllers/BatchExportController.php @@ -56,7 +56,7 @@ public function batchExport(Request $request, $project_id) /** @var Collection $documents */ $documents = $project->pages; - $navigators = navigatorSort(navigator($project_id, 0)); + $navigators = navigatorSort(navigator($project_id, 0), $project->catalog_sort_style); if ($pid !== 0) { $navigators = $this->filterNavigators($navigators, function (array $nav) use ($pid) { diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index d7729fb5..5ec19032 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -364,12 +364,14 @@ private function basicSettingHandle(Request $request, Project $project): bool $this->validate( $request, [ - 'name' => 'required|between:1,100', - 'description' => 'max:255', - 'project_id' => "required|in:{$project->id}|project_exist", - 'visibility' => 'required|in:1,2', - 'sort_level' => 'integer|between:-999999999,999999999', - 'catalog' => 'required|integer', + 'name' => 'required|between:1,100', + 'description' => 'max:255', + 'project_id' => "required|in:{$project->id}|project_exist", + 'visibility' => 'required|in:1,2', + 'sort_level' => 'integer|between:-999999999,999999999', + 'catalog' => 'required|integer', + 'catalog_sort_style' => 'in:0,1', + 'catalog_fold_style' => 'in:0,1,2', ], [ 'name.required' => __('project.validation.project_name_required'), @@ -383,11 +385,15 @@ private function basicSettingHandle(Request $request, Project $project): bool $visibility = $request->input('visibility'); $sortLevel = $request->input('sort_level'); $catalog = $request->input('catalog'); + $catalogSortStyle = $request->input('catalog_sort_style', Project::SORT_STYLE_DIR_FIRST); + $catalogFoldStyle = $request->input('catalog_fold_style', Project::FOLD_STYLE_AUTO); $project->name = $name; $project->description = $description; $project->visibility = $visibility; $project->catalog_id = empty($catalog) ? null : $catalog; + $project->catalog_fold_style = $catalogFoldStyle; + $project->catalog_sort_style = $catalogSortStyle; if (\Auth::user()->can('project-sort') && $sortLevel != null) { $project->sort_level = (int)$sortLevel; } diff --git a/app/Repositories/Project.php b/app/Repositories/Project.php index a3b7f24e..f67ac6c1 100644 --- a/app/Repositories/Project.php +++ b/app/Repositories/Project.php @@ -36,6 +36,8 @@ * @property \Carbon\Carbon|null $deleted_at * @property int $sort_level 项目排序,排序值越大越靠后 * @property int|null $catalog_id 目录ID + * @property int $catalog_fold_style 目录展示样式 + * @property int $catalog_sort_style 目录排序样式 * @method static \Illuminate\Database\Eloquent\Builder|\App\Repositories\Project whereCatalogId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Repositories\Project whereCreatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Repositories\Project whereDeletedAt($value) @@ -70,6 +72,27 @@ class Project extends Repository */ const PRIVILEGE_RO = 2; + /** + * 目录折叠样式:自动 + */ + const FOLD_STYLE_AUTO = 0; + /** + * 目录折叠样式:全部展开 + */ + const FOLD_STYLE_UNFOLD = 1; + /** + * 目录折叠样式:全部折叠 + */ + const FOLD_STYLE_FOLD = 2; + /** + * 排序样式:文件夹优先 + */ + const SORT_STYLE_DIR_FIRST = 0; + /** + * 排序样式:自由排序 + */ + const SORT_STYLE_FREE = 1; + protected $table = 'wz_projects'; protected $fillable = [ @@ -79,6 +102,8 @@ class Project extends Repository 'user_id', 'sort_level', 'catalog_id', + 'catalog_fold_style', + 'catalog_sort_style', ]; public $dates = ['deleted_at']; @@ -111,7 +136,7 @@ public function user() public function groups() { return $this->belongsToMany(Group::class, 'wz_project_group_ref', 'project_id', 'group_id') - ->withPivot('created_at', 'updated_at', 'privilege'); + ->withPivot('created_at', 'updated_at', 'privilege'); } /** diff --git a/app/helpers.php b/app/helpers.php index 4d77b9e8..ae2efcda 100644 --- a/app/helpers.php +++ b/app/helpers.php @@ -8,6 +8,7 @@ use App\Repositories\Catalog; use App\Repositories\Document; +use App\Repositories\Project; use App\Repositories\Template; use App\Repositories\User; use Carbon\Carbon; @@ -130,10 +131,11 @@ function ($nav) { * 导航排序,排序后,文件夹靠前,普通文件靠后 * * @param array $navItems + * @param int $sortStyle * * @return array */ -function navigatorSort($navItems) +function navigatorSort($navItems, $sortStyle = Project::SORT_STYLE_DIR_FIRST) { $sortItem = function ($a, $b) { try { @@ -153,7 +155,10 @@ function navigatorSort($navItems) usort( $navItems, - function ($a, $b) use ($sortItem) { + function ($a, $b) use ($sortItem, $sortStyle) { + if ($sortStyle == Project::SORT_STYLE_FREE) { + return $sortItem($a, $b); + } $aIsFolder = !empty($a['nodes']); $bIsFolder = !empty($b['nodes']); diff --git a/database/migrations/2021_03_29_133806_add_project_menu_control.php b/database/migrations/2021_03_29_133806_add_project_menu_control.php new file mode 100644 index 00000000..14374045 --- /dev/null +++ b/database/migrations/2021_03_29_133806_add_project_menu_control.php @@ -0,0 +1,33 @@ +tinyInteger('catalog_fold_style')->default(0)->comment('目录展开样式:0-自动 1-全部展开 2-全部折叠'); + $table->tinyInteger('catalog_sort_style')->default(0)->comment('目录排序样式:0-目录优先 1-自由排序'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('wz_projects', function (Blueprint $table) { + $table->dropColumn(['catalog_fold_style', 'catalog_sort_style']); + }); + } +} diff --git a/public/assets/js/navigator-tree.js b/public/assets/js/navigator-tree.js index e35b2538..8fd70e78 100644 --- a/public/assets/js/navigator-tree.js +++ b/public/assets/js/navigator-tree.js @@ -9,10 +9,12 @@ * 导航树 * * @param left_nav + * @param mode 0-自动 1-全部展开 2-全部折叠 */ -$.wz.navigator_tree = function (left_nav) { +$.wz.navigator_tree = function (left_nav, mode) { var icon_close = 'fa fa-folder-o'; var icon_open = 'fa fa-folder-open-o'; + mode = mode || 0; var childrenShow = function (elementLi) { elementLi.children('ul').show(); @@ -21,29 +23,74 @@ $.wz.navigator_tree = function (left_nav) { return elementLi; }; - // 先隐藏所有的li下的子元素 - left_nav.find('li.wz-has-child').children('ul').hide(); - // 在包含子元素的li中添加展开图标和链接 - left_nav.find('li.wz-has-child').prepend(''); - // 菜单折叠事件处理 - left_nav.find('li.wz-has-child').find('.wz-nav-fold') - .on('click', function () { - if ($(this).hasClass(icon_close)) { - $(this).removeClass(icon_close).addClass(icon_open); - } else { - $(this).removeClass(icon_open).addClass(icon_close); - } + switch (mode) { + case 0: // 自动 + (function () { + // 先隐藏所有的li下的子元素 + left_nav.find('li.wz-has-child').children('ul').hide(); + // 在包含子元素的li中添加展开图标和链接 + left_nav.find('li.wz-has-child').prepend(''); + // 菜单折叠事件处理 + left_nav.find('li.wz-has-child').find('.wz-nav-fold') + .on('click', function () { + if ($(this).hasClass(icon_close)) { + $(this).removeClass(icon_close).addClass(icon_open); + } else { + $(this).removeClass(icon_open).addClass(icon_close); + } - $(this).parent().children('ul').slideToggle('fast'); - }); + $(this).parent().children('ul').slideToggle('fast'); + }); - left_nav.find('.wz-auto-open').children('li.wz-has-child').each(function () { - var childrenCount = $(this).children('ul').children('li').length; - // 如果一级菜单的子元素小于7个,则自动展开 - if (childrenCount < 7) { - $(this).children('a.wz-nav-fold').trigger('click'); - } - }); + left_nav.find('.wz-auto-open').children('li.wz-has-child').each(function () { + var childrenCount = $(this).children('ul').children('li').length; + // 如果一级菜单的子元素小于7个,则自动展开 + if (childrenCount < 7) { + $(this).children('a.wz-nav-fold').trigger('click'); + } + }); + + // 一级元素的子元素自动展示 + childrenShow(left_nav.children('li')); + })(); + break; + case 1: // 全部展开 + (function(){ + // 在包含子元素的li中添加展开图标和链接 + left_nav.find('li.wz-has-child').prepend(''); + // 菜单折叠事件处理 + left_nav.find('li.wz-has-child').find('.wz-nav-fold') + .on('click', function () { + if ($(this).hasClass(icon_close)) { + $(this).removeClass(icon_close).addClass(icon_open); + } else { + $(this).removeClass(icon_open).addClass(icon_close); + } + + $(this).parent().children('ul').slideToggle('fast'); + }); + })() + break; + case 2: // 全部折叠 + (function(){ + // 先隐藏所有的li下的子元素 + left_nav.find('li.wz-has-child').children('ul').hide(); + // 在包含子元素的li中添加展开图标和链接 + left_nav.find('li.wz-has-child').prepend(''); + // 菜单折叠事件处理 + left_nav.find('li.wz-has-child').find('.wz-nav-fold') + .on('click', function () { + if ($(this).hasClass(icon_close)) { + $(this).removeClass(icon_close).addClass(icon_open); + } else { + $(this).removeClass(icon_open).addClass(icon_close); + } + + $(this).parent().children('ul').slideToggle('fast'); + }); + })() + break; + } // 当前选中元素的所有父级元素全部自动展开 left_nav.find('li.active').parents('ul').show(); @@ -54,10 +101,6 @@ $.wz.navigator_tree = function (left_nav) { // 当前选中元素的下级元素自动展开 childrenShow(left_nav.find('li.active')); - - // 一级元素的子元素自动展示 - childrenShow(left_nav.children('li')); - left_nav.find('li:not(.wz-has-child)').map(function () { var nav_icon = ($(this).data('type') === 'swagger' ? 'fa-code' : ($(this).data('type') === 'markdown' ? 'fa-file-text-o' : 'fa-table')); $(this).prepend(''); diff --git a/resources/views/components/navbar-edit.blade.php b/resources/views/components/navbar-edit.blade.php index 46105719..e8a07870 100644 --- a/resources/views/components/navbar-edit.blade.php +++ b/resources/views/components/navbar-edit.blade.php @@ -1,5 +1,5 @@ @php $___index = 0; @endphp -@foreach(navigatorSort($navbars) as $nav) +@foreach(navigatorSort($navbars, $project->catalog_sort_style) as $nav)
  • @@ -13,7 +13,7 @@ @if(!empty($nav['nodes'])) @endif
  • diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index e7eaf85a..356ec467 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -1,5 +1,5 @@ -@foreach(navigatorSort($navbars) as $nav) +@foreach(navigatorSort($navbars, $project->catalog_sort_style) as $nav)
  • @if($nav['status'] == \App\Repositories\Document::STATUS_OUTDATED) @@ -11,7 +11,7 @@ @if(!empty($nav['nodes'])) @endif
  • diff --git a/resources/views/layouts/project.blade.php b/resources/views/layouts/project.blade.php index 9876757b..6ab8aff5 100644 --- a/resources/views/layouts/project.blade.php +++ b/resources/views/layouts/project.blade.php @@ -54,7 +54,7 @@
    @@ -116,7 +116,7 @@