2014-03-30 66 views
0

我们有一个电子商务网站,几年来一直在销售一天的产品。我们有一个可以订购产品的系统,所以'特色'产品处于顶端,而不畅销的产品处于折叠下方的底部。不同长度的产品分类

我们最近推出了几天运行的产品,而不仅仅是一个,但是这对我们的排序算法造成了严重破坏。

以前我们设置一天天基础的产品订单,所以如果我们在第一天有5种产品的销售,我们会设置它像这样在数据库:

Position | Product 
---------------------- 
1  | Product # 1 
5  | Product # 2 
4  | Product # 3 
2  | Product # 4 
3  | Product # 5 

然后我们可以拉一天中的产品清单,按位置排序和显示。但是现在,我们必须补偿跨多天运行的产品,因此可能会在多天内拥有多个职位。我们认为,我们可以很容易地调整我们的算法,在整个产品的表像这样运行:

Position | Product 
---------------------- 
51  | Product # 1 
75  | Product # 2 
69  | Product # 3 
62  | Product # 4 
66  | Product # 5 

这些产品仍然以相同的顺序,因为他们原本,但位置是基于表中的每一个产品,而不仅仅是那一天。这给我们一个日历,这是我们所期望的(该数字是产品表中的当前位置): enter image description here

问题出现在我们要重新订购产品时。如果我们的产品#6运行了3天,它可能会有64位,这使得它在当天#4和#3以上,但是当我们重新订购这些产品时,它会移动并获得jQuery UI数据在与任何事物无关的名单中,虽然我们知道产品与其他日子的关系,但我们不知道这些日子是如何相互关联的。

我们现在每次放置后都会有回调触发,所以我们只需要处理一次正在移动的产品。这减少了我们需要做的计算,但我们宁愿一次设置订单并从那里进行处理。这也给用户一个中止的机会。

这是我们目前的排序算法插入该产品在两个人之间:

public function setPosition($after, $before) 
{ 
    // Get products which this product is after and before 
    $after = $this->find($after); 
    $before = $this->find($before); 

    // Move all items down to clear a space for the product 
    $this->where('position', '>', $before->position)->update(array('position', DB::raw('position + 1'))); 

    $this->position = $after->position + 1; 
    $this->updateUniques(); 
} 

我们相信我们不仅谁也遇到了这个问题,认为必须有办法的人解决这个问题。

+0

-sorry我哑巴的问题,但你如何生成这些表格文本? – Bonik

+0

四个空格然后一些破折号 – sjdaws

回答

0

这不是完美的,但不是移动产品本身,我结束了移动受影响的产品,它似乎工作。

数据作为数组从jQueryUI排序传递。

该控制器具有此更新功能:

/** 
* Update the schedule order 
* 
* @return object 
*/ 
public function update() 
{ 
    // Find product before and after 
    foreach (Input::get('order') as $key => $product) 
    { 
     if ($product['id'] != Input::get('id')) continue; 

     // Find the products before or after this product 
     $before = Input::get('order.' . ($key - 1) . '.id') ?: 0; 
     $after = Input::get('order.' . ($key + 1) . '.id') ?: 0; 
     break; 
    } 

    // Find product 
    $product = Product::find(Input::get('id')); 

    $product->updatePosition($before, $after); 

    return $this->get(); 
} 

该模型具有此updatePosition功能:

/** 
* Move/reorder a product into another position 
* 
* @param int $before [= 0] 
* @param int $after [= 0] 
* @return void 
*/ 
public function updatePosition($before = 0, $after = 0) 
{ 
    // Get products which are before or after this product 
    $before = $this->find($before); 
    $after = $this->find($after); 

    // Determine which direction we've moved this product 
    if (! $before) $direction = -1; 
    elseif (! $after) $direction = 1; 
    elseif ($before->position < $this->position && $after->position < $this->position) $direction = -1; 
    else $direction = 1; 

    // Determine how much we've moved 
    if ($direction == 1) 
    { 
     // We've moved this product down 
     $difference = $this->position - $before->position - 1; 
     $this->whereNull('parent_id')->where('position', '<=', $before->position)->where('id', '!=', $this->id)->update(array('position' => DB::raw('position + ' . $difference))); 
    } 
    else 
    { 
     $difference = $this->position - $after->position + 1; 
     $this->whereNull('parent_id')->where('position', '>=', $after->position)->where('id', '!=', $this->id)->update(array('position' => DB::raw('position + ' . $difference))); 
    } 
} 

这样做的缺点是我还有每一滴后保存,而不是重新排序堆的产品和工作出他们的新职位,但它的工作原理...

0

我认为它真的很重要什么“位置”条目时,你显示它们。唯一重要的是显示的条目的相对位置。所以,你可以换个位置。因此,在你的第二个例子,

Position | Product 
---------------------- 
51  | Product # 1 
75  | Product # 2 
69  | Product # 3 
62  | Product # 4 
66  | Product # 5 

如果你想交换产品2和第3,只设置#2的位置69和#3位到75

Position | Product 
---------------------- 
51  | Product # 1 
75  | Product # 3 
69  | Product # 2 
62  | Product # 4 
66  | Product # 5 

如果我理解你正确地说,我认为这不会影响其他日子。

要做到这一点,我会在HTML元素上使用data属性,如data-position,并将其设置为从数据库返回的值。然后在jQuery中,当你交换行时,你有两个data-position可以很容易地被AJAX发送到你的SQL查询来交换位置。

如果您决定重新排列所有条目并发送一个回调,这也应该起作用。当您启动回拨时,只需使用它们的data-position作为每个元素。

希望这是有道理的。

+0

感谢迈克,这是非常有意义的。问题是产品跨越多天。它的相对位置与产品不同,取决于我们正在查看哪一天。如果我们有一个位置为10的多日产品,并且我们在某一天的某个位置将产品移动到产品上方的位置为5,那么我们将如何在第二天对产品执行6位置操作低于? – sjdaws

+0

@sjdaws在没有整个集合的知识的情况下,相对于整个数据集不能定位一小部分数据样本。如果你有位置10,15,20和25,则无法知道你想将物品从位置25移动到位置17,而不使用它们之间的物品。所有你知道的是它在16到19之间。所以基本上你必须一次调整它,或者使用整个集合而不是一个小样本。 – Mike

+0

例如,在上面的图片中,如果您想将“软谨慎前置理论127”移动一个位置,您怎么知道在这个和“赤道内建议124”之间没有别的东西?也许有,也许没有。你可以做的唯一事情就是把它移到另一个之上,如果这两者之间存在某种东西,那么去一个有另一个可用的日期并翻转它们。 – Mike