上一篇说到如何在前端作多张图片的拖动排序,这篇将会从数据库表的角度,看如何记录这些图片的顺序。javascript
首先想到的是在数据库photo表
中添加字段order
,用来记录图片在其所在的相册中的位置.表的结果相似于
album_id是图片所在相册的idhtml
用户上传图片时,选出相册最大的order,前端
select max(order) from photo where album_id=?
而后在插入行的时候,order列是max(order)+1.java
图片移动到其余相册时,修改album_id为目标相册album_id,而后像上面,选出目标相册最大的order,并将其设置为要移动的图片order.程序员
多张图片拖动排序时,。。。本屌不敢想象,太复杂了。sql
和上面添加order
字段相似,这里添加字段update_time
,表示图片最近一次更新的时间。数据库
上传图片,update_time
是上传时间。segmentfault
移动图片,update_time
是移动操做当前的时间。ui
图片拖动排序,好比
图片移动到图片2,3之间,这时,将被移动图片的update_time
设置为图片2,3的update_time之和除以2
,以确保顺序。
若是拖动的是多张图片,好比拖动2张,那第2张图片的update_time
是上图中第3(第一张拖动图片)
,4张图片的update_time之和除以2
.其余的依次类推。spa
qq空间里图片的批量管理,也有拖动排序。看下传递给后台的参数
codeList
是选中拖动图片的photo_id,以_
做为分隔符,这里选中了3张图片。prevKey
,nextKey
是拖动的目标位置左右两边图片的photo_id.prevIdx
,nextIdx
是拖动的目标位置左右两边图片的索引,这里是想把图片插到第2,3张图片之间。
看到上面的参数,是否是很容易想到双向链表
?
上图是相册没有进行过任何拖动排序的状况,prev
,next
字段为0分别表示该图片已经相册是第一张或最后一张图片。
如今拖动排序,图片从左到右的photo_id
依次为1-8,拖动的图片photo_id
是7,目标是photo_id
是2,3的图片之间。
具体操做
选出拖动图片的prev
,next
select prev,next from photo where photo_id=7
选出拖动图片的前一张(若是有)图片和后一张(若是有)图片
select photo_id as prev_photo from photo where photo_id<7 limit 1 select photo_id as next_photo from photo where photo_id>7 limit 1
将拖动图片的前一张图片和后一张图片连起来
update photo set next=next_photo where photo_id=prev_photo update photo set prev=prev_photo where photo_id=next_photo
将拖动图片插到目标位置
update photo set next=7 where photo_id=2 update photo set prev=7 where photo_id=3 update photo set prev=2,next=3 where photo_id=7
这里只拖动了一张图片,若是拖动多张的话,代码就要复杂些,由于拖动的各照片要构建双向链表
。本屌暂时不写多张拖动的状况,之后有时间的话会补上。
找到最后一张图片
select photo_id as last_photo from photo where next=0
上传图片
上传的图片放到最后
update photo set next=upload_photo where photo_id=last_photo update photo set prev=last_photo,next=0 where photo_id=upload_photo
选出拖动图片的prev
,next
select prev as prev_photo,next as next_photo from photo where photo_id=7
将删除图片的前一张图片和后一张图片连起来
update photo set next=next_photo where photo_id=prev_photo update photo set prev=prev_photo where photo_id=next_photo
删除图片
前面的操做都是在一个相册中进行,因此where条件中就没写album_id.
qq空间中图片移动到另外一个相册,图片会被排到相册的最后一个位置,这里也同样。
具体的
选出移动图片的prev
,next
select prev,next from photo where photo_id=move_photo
选出移动图片的前一张(若是有)图片和后一张(若是有)图片
select photo_id as prev_photo from photo where photo_id<move_photo limit 1 select photo_id as next_photo from photo where photo_id>move_photo limit 1
将移动图片的前一张图片和后一张图片连起来
update photo set next=next_photo where photo_id=prev_photo update photo set prev=prev_photo where photo_id=next_photo
找到另外一个相册中的最后一张图片
select photo_id as last_photo from photo where next=0 and album_id=another_album
移动的图片放到最后
update photo set next=move_photo where photo_id=last_photo
设置移动图片的prev
,next
update photo set prev=last_photo,next=0 where photo_id=move_photo
双向链表
如何呈现?上一节说的是在不一样场景下,数据库表该如何变化,实际就是很简单的双向链表
操做。可是若是用这种表结构不能按用户自定义的顺序把图片呈现出来,仍是没什么卵用。
下面说说怎么呈现。
一般图片都是按时间降序排列,这里简单的用order by photo_id desc
表示.而自定义的顺序
不能简单的经过对prev
,next
列的排序得到。
var data=[//顺序:5 2 3 9 8 1 4 10 7 6 {id:10,prev:4,next:7}, {id:9,prev:3,next:8}, {id:8,prev:9,next:1}, {id:7,prev:10,next:6}, {id:6,prev:7,next:0}, {id:5,prev:0,next:2}, {id:4,prev:1,next:10}, {id:3,prev:2,next:9}, {id:2,prev:5,next:3}, {id:1,prev:8,next:4} ];
既然数据库不能排序就只有写代码排序了。这里用js排序,代码很简单,没几行
顺序:5 2 3 9 8 1 4 10 7 6 <div ms-controller='sort'> <ul> <li ms-repeat='list'> pic{{el.id}} prev:{{el.prev}} next:{{el.next}} </li> </ul> </div>
require(['avalon'],function(avalon){ var sort=avalon.define({ $id:'sort', list:[] }); avalon.scan(); var data=[//先按时间降序排列,而后自定义顺序:5 2 3 9 8 1 4 10 7 6 {id:10,prev:4,next:7}, {id:9,prev:3,next:8}, {id:8,prev:9,next:1}, {id:7,prev:10,next:6}, {id:6,prev:7,next:0}, {id:5,prev:0,next:2}, {id:4,prev:1,next:10}, {id:3,prev:2,next:9}, {id:2,prev:5,next:3}, {id:1,prev:8,next:4} ]; var next=0,result=[],photo_id_arr=[];//photo_id_arr保存全部的photo_id data.sort(function(a,b){//排序只是为了保证data[0]取到的是链表的头元素 return a.prev-b.prev; }); avalon.each(data,function(i,el){ photo_id_arr.push(el.id); }); while(next!=-1){//若是元素的next(即下一个photo_id)在photo_id_arr中存在 var cur=data[next]; result.push(cur); next=photo_id_arr.indexOf(cur.next); } sort.list=result; });
例子下载
本屌非开发qq空间相册的程序员,以上纯属猜想。若有雷同,纯属巧合