arneetsingh/laravel-customsort

一个用于手动按自定义顺序排序Eloquent模型记录的包

1.0.0 2022-05-19 15:19 UTC

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

解决的问题

例如,需要显示某些帖子记录,例如在列表页面上显示置顶帖子。只需通过用户设置的自定义顺序显示特定帖子。

安装

您可以通过composer安装此包

composer require arneetsingh/laravel-customsort

使用以下命令发布并运行迁移

php artisan vendor:publish --tag="laravel-customsort-migrations"
php artisan migrate

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="laravel-customsort-config"

使用方法

模型

在您想要手动排序功能的模型中使用 CanCustomSort 特性。

<?php

namespace App\Models;

use ArneetSingh\CustomSort\Traits\CanCustomSort;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use CanCustomSort;
}

设置排序

假设我们Post模型中有5个帖子,我们想按id顺序2,4,1,5,3设置它们。

Post::setNewOrder([2, 4, 1, 5, 3]);

请注意,您不需要传递所有帖子,尽管您可以选择这样做。只传递的帖子将按此顺序返回到顶部。

以自定义顺序获取数据

Post::orderByCustom()->get();

将按设置的顺序返回帖子,然后是其余的帖子。

按模型设置优先级

$post->setOrderPriority(10);

如果优先级编号高于其他帖子,它将被移动到结果顶部。

示例

假设我们Post模型中有5个帖子,我们想按id顺序2,4,1,5,3设置它们。

Request: PUT
Endpoint: /posts/customSort
Payload:
{
	"custom_sort":[
		{
			"id":2,
			"priority":5			
		},
		{
			"id":4,
			"priority":4			
		},
		{
			"id":1,
			"priority":3			
		},
		{
			"id":5,
			"priority":2			
		},
		{
			"id":3,
			"priority":1			
		}
	]
}

控制器代码可能如下所示

    public function store(Request $request)
    {
        $request->validate([
            'custom_sort' => 'required',
            'custom_sort.*.id' => "required|exists:posts,id",
            'custom_sort.*.priority' => 'required|integer'
        ]);
        
        $morphClass = (new Post())->customSort()->getMorphClass();
        collect($request->custom_sort)->transform(function ($item) use($morphClass) {
            CustomSort::create([
                'sortable_id' => $item['id'],
                'sortable_type' => $morphClass,
                'priority' => $item['priority']
            ]);
        });
    }

前端提示

我使用了 SortabelJS 以实现拖放设置手动顺序的功能。以下是JavaScript代码片段。

let posts = []

// SortableJS onEnd handler would look like this
onEnd: function ({ oldIndex, newIndex }){
  const movedItem = posts.splice(oldIndex, 1)[0]
  posts.splice(newIndex, 0, movedItem)
}

// prepare payload
preparePayload: function() {
  const order = posts.map((item, key) => {
    return {
      id: item.id,
      priority: posts.length - key
    }
  })
  return { custom_sort: order }
}

测试

composer test

变更日志

请参阅 CHANGELOG 了解最近的变化信息。

贡献

请参阅 CONTRIBUTING 了解详细信息。

安全漏洞

请查阅 我们的安全策略 了解如何报告安全漏洞。

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅 许可证文件