2014-03-30 68 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