拖动排序函数的改写

Teemo 8天前 49

有过这问题 ? 看看 : 别看;

今天在整合新最版fa时,发现拖动排序有点问题,看源码,有点晕,故索性改写。

实现思路

减权重

image.png

增权重

image.png

改写后的函数代码

application/admin/controller/Ajax.php 个人习惯的不美观表达式~~~

public function weigh()
{
    //排序的数组
    $ids = $this->request->post("ids");
    //拖动的记录ID
    $changeid = $this->request->post("changeid");
    //操作字段
    $field = $this->request->post("field");
    //操作的数据表
    $table = $this->request->post("table");
    //排序的方式
    $orderway = $this->request->post("orderway", "", "strtolower");
    $orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
    $sour = $weighdata = [];
    $ids = explode(',', $ids);
    $prikey = 'id';
    $pid = $this->request->post("pid");

    $row =  Db::name($table)->find($changeid);

    //原权重
    $oldWeigh = $row[$field] ?: 0;
    //新权重的计算
    $count = count($ids);
    $point = array_search($changeid, $ids);
    $newWeigh     = null; //新权重
    $biggerWeigh  = null; //新权重相邻较大者权重
    $smallerWeigh = null; //新权重相邻较小者权重

    if ($orderway === 'DESC') {
        $biggerWeigh  = $point === 0 ? Db::name($table)->find($ids[0])[$field] + 1 : Db::name($table)->find($ids[$point - 1])[$field];
        $smallerWeigh = $point === $count - 1 ? Db::name($table)->find($ids[$point])[$field] - 1 : Db::name($table)->find($ids[$point + 1])[$field];
    } else if ($orderway === 'ASC') {
        $biggerWeigh  = $point === $count - 1 ? Db::name($table)->find($ids[$count - 1])[$field] + 1 : Db::name($table)->find($ids[$point + 1])[$field];
        $smallerWeigh = $point === 0 ? Db::name($table)->find($ids[0])[$field] - 1 : Db::name($table)->find($ids[$point - 1])[$field];
    }
    $newWeigh = $oldWeigh > $biggerWeigh ? $biggerWeigh : $smallerWeigh;

    //修改权重
    if ($oldWeigh > $biggerWeigh) {
        //减重
        Db::name($table)->where([$field=> [['>=', $biggerWeigh], ['<=', $oldWeigh]]])->update([$field=> Db::raw($field . '+1')]);
    } else if ($oldWeigh < $smallerWeigh) {
        //加重
        Db::name($table)->where([$field=> [['<=', $smallerWeigh], ['>=', $oldWeigh]]])->update([$field=> Db::raw($field . '-1')]);
    }
    Db::name($table)->where($prikey, $changeid)->update([$field=> $newWeigh]);

    $this->success();
}

扩展

以上的更改已基本够用,但有时业务场景对排序的数据有限制。比如,要排序某商品的规格,这时只需要排序属于该商品下的规格,而其它商品的规格不能受影响。而且改动的数据小对性能也有好处,所以来扩展一下拖动排序功能。

前端增加发送"限制字段"参数

/pulbic/assets/js/require-table.js Table.api.bindevent()

image.png

后端处理排序时加上字段限制 (即:与拖动目标某些字段的值相等的数据才改变权重)

application/admin/controller/Ajax.php 完整weigh()

public function weigh()
{
    //排序的数组
    $ids = $this->request->post("ids");
    //拖动的记录ID
    $changeid = $this->request->post("changeid");
    //操作字段
    $field = $this->request->post("field");
    //操作的数据表
    $table = $this->request->post("table");
    //排序的方式
    $orderway = $this->request->post("orderway", "", "strtolower");
    $orderway = $orderway == 'asc' ? 'ASC' : 'DESC';
    $sour = $weighdata = [];
    $ids = explode(',', $ids);
    $prikey = 'id';
    $pid = $this->request->post("pid");

    $row =  Db::name($table)->find($changeid);

    //排序限制
    $sortLimitFileds = $this->request->post("sortlimit/a", []);
    $whereExtned = [];
    foreach ($sortLimitFileds as $limitField) {
        $whereExtned[$limitField] = $row[$limitField];
    }

    //原权重
    $oldWeigh = $row[$field] ?: 0;
    //新权重的计算
    $count = count($ids);
    $point = array_search($changeid, $ids);
    $newWeigh     = null; //新权重
    $biggerWeigh  = null; //新权重相邻较大者权重
    $smallerWeigh = null; //新权重相邻较小者权重

    if ($orderway === 'DESC') {
        $biggerWeigh  = $point === 0 ? Db::name($table)->find($ids[0])[$field] + 1 : Db::name($table)->find($ids[$point - 1])[$field];
        $smallerWeigh = $point === $count - 1 ? Db::name($table)->find($ids[$point])[$field] - 1 : Db::name($table)->find($ids[$point + 1])[$field];
    } else if ($orderway === 'ASC') {
        $biggerWeigh  = $point === $count - 1 ? Db::name($table)->find($ids[$count - 1])[$field] + 1 : Db::name($table)->find($ids[$point + 1])[$field];
        $smallerWeigh = $point === 0 ? Db::name($table)->find($ids[0])[$field] - 1 : Db::name($table)->find($ids[$point - 1])[$field];
    }
    $newWeigh = $oldWeigh > $biggerWeigh ? $biggerWeigh : $smallerWeigh;

    //修改权重
    if ($oldWeigh > $biggerWeigh) {
        //减重
        Db::name($table)->where($whereExtned)->where([$field=> [['>=', $biggerWeigh], ['<=', $oldWeigh]]])->update([$field=> Db::raw($field . '+1')]);
    } else if ($oldWeigh < $smallerWeigh) {
        //加重
        Db::name($table)->where($whereExtned)->where([$field=> [['<=', $smallerWeigh], ['>=', $oldWeigh]]])->update([$field=> Db::raw($field . '-1')]);
    }
    Db::name($table)->where($prikey, $changeid)->update([$field=> $newWeigh]);

    $this->success();
}

使用方法

进行以上改动之后,我们便能在前端初始化表格时,指定"一些"同值限制字段(如:商品ID)。这样,后端排序时,只有该商品ID下的规格才会改变权重。

image.png

考虑了临界情况,并经个人测试,代码可按预想工作

若你有更好实现方法欢迎留言分享,或Q 2506505996。
最新回复 (0)
返回