1.问题描述
最终效果如下:
这些排序需要进行全部数据的排序而不是根据当前页面进行排序
旧逻辑是将数据全查出来由前端进行分页和排序 我感觉难受就改成后端分页了 然而会导致只排序当前页的问题 所以需要修改排序逻辑也移动到后台中
2.前端代码如下
1.html代码:
<el-table border
ref="multipleTable"
:data="gameList"
:row-class-name="gameRowTableClass"
stripe
tooltip-effect="dark"
style="width: 100%"
:row-key="getRowKeys"
@sort-change="sort_change"
>
<el-table-column
type="selection"
:reserve-selection="true"
width="55">
</el-table-column>
<el-table-column
type="index"
label="编号"
width="50">
</el-table-column>
<el-table-column label="吸量" align="center">
<el-table-column prop="avgUserClickPoint" sortable="custom" label="平均用户点击率" :formatter="formatterPercent" >
</el-table-column>
</el-table-column>
<el-table-column label="活跃" align="center">
<el-table-column prop="avgDayAliveUserPercent" sortable="custom" label="平均日活用户" >
</el-table-column>
<el-table-column sortable="custom" prop="sumActivityUserCount" label="累计活跃用户">
</el-table-column>
<el-table-column sortable="custom" prop="sumPlayCount" label="累计游戏频次">
</el-table-column>
</el-table-column>
<el-table-column label="质量" align="center">
<el-table-column sortable="custom" prop="avgPersonPlayCount" label="人均游戏频次">
</el-table-column>
<el-table-column sortable="custom" prop="avgPersonPlayDuration" label="人均游戏时长">
</el-table-column>
<el-table-column sortable="custom" prop="avgSecondaryPercent" label="平均次日留存率" :formatter="formatterPercent">
</el-table-column>
</el-table-column>
<el-table-column label="新品" align="center">
<el-table-column sortable="custom" prop="dtCreate" :formatter="formatDate" label="游戏发布时间">
</el-table-column>
<el-table-column sortable="custom" prop="dtUpdate" :formatter="formatDate" label="游戏更新时间">
</el-table-column>
</el-table-column>
</el-table>
<div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryGameSelector.page"
:page-sizes="[5, 10,20,30]"
:page-size="queryGameSelector.pageSize"
layout="total, sizes, prev, pager, next"
:total="totalElements">
</el-pagination>
</div>
2.data 数据
只把需要用到的放着了
// 游戏选品 上边表格的数据结构
queryGameSelector: {
"gameIds": [],
"categories": [],
"state": 1,
"startTime": '',
"endTime": '',
"subChannelIds": [],
"orderColumn": '',
"orderType": '',
"page": 1,
"pageSize": 10
},
3.method — sortChange方法
sort_change(column) {
this.queryGameSelector.page=1;
//如果列空则条件清空 如果order为null手动置为空字符串 如果其他情况设置字段
if(column.prop == null ){
this.queryGameSelector.orderColumn = "";
this.queryGameSelector.orderType = ""
}else {
if( column.order == null){
this.queryGameSelector.orderType = ""
}else {
this.queryGameSelector.orderType = column.order
}
this.queryGameSelector.orderColumn = column.prop
}
//这里调用后台接口将orderType orderColumn 传入
this.gameSelectorTemp()
},
3.后端代码如下:
1.后台逻辑主要是通过filter stream 流处理进行排序 并进行手动分页
因为之前查询sql代码过于复杂没法加入排序分页逻辑只能后台进行处理
//第四步 手动分页进行处理
long page=0;
Integer pageSize= 30;
long total=0;
//设置总记录数 修改总数量计算值为beforeRes 因为在calculateGameSelector 方法中进行了游戏版本判断 可能会减少部分数据
if(!CollectionUtils.isEmpty(beforeRes)){
total= beforeRes.size();
}
//设置分页信息
if(Objects.nonNull(search.getPage()) && search.getPage()>0){
page=search.getPage()-1;
}
//设置大小
if(Objects.nonNull(search.getPageSize()) ){
pageSize=search.getPageSize();
}
List<GameSelectorReportPojo> afterList =null;
// 第四步: 进行排序及分页处理 当排序两个字段都非空的时候进行排序逻辑 后端排序实现 可以进行优化 方案一当前采用后端进行分页实现排序 方案二 采用sql语句形式进行查询 一次即可查询出符合要求的数据并进行分页排序 因为临时字段jpa分页有问题所以暂时没弄出来
if( Strings.isNotBlank(search.getOrderColumn()) && Strings.isNotBlank(search.getOrderType())){
//普通排序
afterList= beforeRes.stream().sorted((o1, o2) -> {
int reverse=1;
//已经判断非空了 如果是降序取负数即可
if("descending".equals(search.getOrderType())){
reverse=-1;
}
switch (search.getOrderColumn()){
case "avgUserClickPoint":{
return (int) (o1.getAvgUserClickPoint()-o2.getAvgUserClickPoint())*reverse;
}
case "sumActivityUserCount":{
return (int) (o1.getSumActivityUserCount()-o2.getSumActivityUserCount())*reverse;
}
case "avgDayAliveUserPercent":{
return (int) (o1.getAvgDayAliveUserPercent()-o2.getAvgDayAliveUserPercent())*reverse;
}
case "sumPlayCount":{
return (int) (o1.getSumPlayCount()-o2.getSumPlayCount())*reverse;
}
case "avgPersonPlayCount":{
return (int) (o1.getAvgPersonPlayCount()-o2.getAvgPersonPlayCount())*reverse;
}
case "avgPersonPlayDuration":{
return (int) (o1.getAvgPersonPlayDuration()-o2.getAvgPersonPlayDuration())*reverse;
}
case "avgSecondaryPercent":{
return (int) (o1.getAvgSecondaryPercent()-o2.getAvgSecondaryPercent())*reverse;
}
case "dtCreate":{
return (int) (o1.getDtCreate().getTime()-o2.getDtCreate().getTime())*reverse;
}
case "dtUpdate":{
return (int) (o1.getDtUpdate().getTime()-o2.getDtUpdate().getTime())*reverse;
}
default:{
//默认排序按照用户点击率进行排序 todo 这里默认值情况没想好怎么处理
return (int) (o1.getAvgUserClickPoint()-o2.getAvgUserClickPoint())*reverse;
}
}
}).skip(page * pageSize).limit(pageSize).collect(Collectors.toList());
}else{
//普通排序
afterList= beforeRes.stream().skip(page * pageSize).limit(pageSize).collect(Collectors.toList());
}
//切分记录
//创建分页对象
PageImpl<GameSelectorReportPojo> resultPage = new PageImpl<>(afterList, PageRequest.of((int) page, pageSize,Sort.unsorted()),total);
return resultPage;
3.参考资料
官方文档-排序
element-ui el-table表格排序sortable参数解析
Vue之sortable实现排序功能