利用周末时间,对自己的项目进行了升级,原来使用的是tkmybatis,改为mybatis plus。但是返回数据的格式变了,导致前端页面自带的字段排序失效了,需要刷新表格才会排序,于是决定在服务端实现排序。
easyui的数据表格datagrid支持多字段排序,可以控制是否通过服务器排序,核心代码如下。
role_list.html文件:
角色列表
role_list.js文件:
let pageList = [10, 20, 50, 100];
$(document).ready(function() {
// 角色数据表格
$("#role_list").datagrid({
url: '/role_account/selectByPage',
striped: true,
multiSort: true,
fitColumns: true,
remoteSort: true,
singleSelect: true,
height: table_height,
pagination: true,
pageList: pageList,
pageSize: pageList[0],
loadFilter: function(result){
if (result.code === 200){
return result.data;
} else {
return null;
}
},
toolbar: [{
iconCls: 'icon-add',
text: '添加',
handler: function() {
handleAdd();
}
}, '-', {
iconCls: 'icon-edit',
text: '修改',
handler: function() {
handleUpdate();
}
}, '-', {
iconCls: 'icon-set',
text: '加点',
handler: function() {
handleJiadian();
}
}, '-', {
iconCls: 'icon-shield',
text: '属性',
handler: function() {
handleAttribute();
}
}, '-', {
iconCls: 'icon-search',
text: '查看',
handler: function() {
handleView();
}
}, '-', {
iconCls: 'icon-tip',
text: '关于',
handler: function() {
handleTip();
}
}],
columns: [[
{field: 'id', title: '角色ID', align: "center", sortable: true, width:100},
{field: 'name', title: '角色名', align: "center", width: 120},
{field: 'modelingId', title: '角色造型', align: "center", width: 80
, formatter: function(value, rowData, rowIndex) {
get("/role_modeling/selectById", {
id: value
}, function(result) {
$("#modeling_" + rowIndex).attr("src", result.image)
.attr("title", result.name);
}, error);
return "";
}
},
{field: 'grade', title: '等级', align: "center", sortable: true, width: 80
, formatter: function(value) {
let group; // 组别
if(value >= 0 && value <= 69) { // [0, 69]精锐组
group = "精锐组";
} else if(value >= 70 && value <= 89) { // [70, 89]勇武组
group = "勇武组";
} else if(value >= 90) { // [90, 115]神威组
group = "神威组";
} else { // [-∞, 0) ∪ (115, +∞)
group = "等级不合法";
}
return "" + value+ "级";
}
},
{field: 'score', title: '人物评分', align: "center", sortable: true, width: 80},
{field: 'schoolId', title: '门派', align: "center", width: 80
, formatter: function(value, rowData, rowIndex) {
get("/school/selectById", {
id: value
}, function(result) {
$("#school_" + rowIndex).attr("src", result.image)
.attr("title", result.name).width(size);
}, error);
return "";
}
},
{field: 'jinbi', title: '金币', align: "center", sortable: true, width: 80},
{field: 'accountId', title: '账号', align: "center", width: 200
, formatter: function(value, rowData, rowIndex) {
get("/account/selectAccountById", {
id: value
}, function(response) {
$("#account_" + rowIndex).html(response.data);
}, error);
return "";
}
},
{field: "lastUpdateTime", title: "最后一次修改时间", align: "center", sortable: true, width: 125},
{field: 'right', title: '操作', align: "center"
, formatter: function(value, rowData, rowIndex) {
return ''
+ '';
}
}
]]
});
});
其中multiSort设置为true表示允许多字段排序,remoteSort表示是否从服务器排序,设置为true,我们接下来在后台接口处理字段排序。
以上是easyui官网的相关截图,当多字段排序时,传递给后台的参数中通过逗号拼接。
【例如】:通过评分score升序和等级grade降序排序时,后台接收到的参数为:
{
"sort": "score,grade"
"order": "asc,desc"
}
controller层:RoleAccountController.java
@RestController
@RequestMapping(path = "/role_account", produces="application/json; charset=utf-8")
public class RoleAccountController {
private final IRoleAccountService service;
@Autowired
public RoleAccountController(IRoleAccountService service) {
this.service = service;
}
@ApiOperation("分页查询角色列表")
@RequestMapping(value = "/selectByPage", method = RequestMethod.POST)
public JsonResult> selectByPage(RoleAccountPager pager) {
Page page = service.selectByPage(pager);
return JsonResult.restPage(page);
}
}
service层:RoleAccountServiceImpl.java
@Service
public class RoleAccountServiceImpl implements RoleAccountService {
@Override
public Page selectByPage(RoleAccountPager pager) {
Page page = new Page<>(pager.getPage(), pager.getRows());
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.eq(
!StringUtils.isEmpty(pager.getId()),
"id", pager.getId());
wrapper.like(
!StringUtils.isEmpty(pager.getName()),
"name", pager.getName()
);
wrapper.eq(
pager.getSchoolId() != null,
"school_id", pager.getSchoolId()
);
wrapper.eq(
pager.getModelingId() != null,
"modeling_id", pager.getModelingId()
);
wrapper.eq(
!StringUtils.isEmpty(pager.getAccountId()),
"account_id", pager.getAccountId()
);
// 得到order by语句
String statement = Pager.getOrderByStatement(pager);
wrapper.last(statement);
return mapper.selectPage(page, wrapper);
}
}
mapper层:RoleAccountMapper.java
@Repository public interface RoleAccountMapper extends BaseMapper{ }
RoleAccount.java
@Data
public class RoleAccount {
@TableId("id")
private String id;
/**
* 角色名
*/
private String name;
/**
* 等级
*/
private Integer grade;
/**
* 人物评分
*/
private Integer score;
/**
* 金币
*/
private Integer jinbi;
/**
* 账号id
*/
private String accountId;
/**
* 门派id
*/
private Integer schoolId;
/**
* 服务器id
*/
private Integer serverId;
/**
* 角色造型id
*/
private Integer modelingId;
/**
* 账号创建时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime birthday;
/**
* 最后一次修改时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime lastUpdateTime;
}
RoleAccountPager.java
@Data
@EqualsAndHashCode(callSuper = true)
public class RoleAccountPager extends Pager {
/**
* 角色id
*/
private String id;
/**
* 角色名
*/
private String name;
/**
* 等级
*/
private Integer grade;
/**
* 账号id
*/
private String accountId;
/**
* 门派id
*/
private Integer schoolId;
/**
* 角色造型id
*/
private Integer modelingId;
}
Pager.java
/**
* 基础分页对象,包含页数和每页的记录数
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class Pager extends Sorter {
/**
* 页数
*/
private Integer page = 1;
/**
* 每页记录数
*/
private Integer rows = 10;
}
Sorter.java
/**
* 基础排序对象,包含排序字段和排序方式
*/
@Data
public class Sorter {
/**
* 排序字段
*/
private String sort;
/**
* 排序方式:asc/desc
*/
private String order;
/**
* 根据查询条件拼接得到order by语句
* @param sorter 分页查询条件
* @return String
*/
public static String getStatement(Sorter sorter) {
String sort;
String[] sortArray = {};
String[] orderArray = {};
String order = sorter.getOrder();
String sortColumn = sorter.getSort();
StringBuilder statement = new StringBuilder();
// 多字段排序
if (StringUtils.isNotEmpty(sortColumn)) {
// 驼峰命名转为下划线
sort = StringUtils.toLowerCase(sortColumn);
if (sort.contains(",")) {
sortArray = sort.split(",");
}
} else {
return "";
}
if (StringUtils.isNotEmpty(order)) {
if (order.contains(",")) {
orderArray = order.split(",");
}
} else {
return "";
}
if (sortArray.length > 0 && orderArray.length > 0) {
int length = sortArray.length;
for (int i = 0; i < length; i++) {
statement.append(sortArray[i]);
statement.append(" ");
statement.append(orderArray[i]);
if (i < length - 1 ) {
statement.append(", ");
}
}
} else {
// " #{sort} #{order}“
statement.append(sort);
statement.append(" ");
statement.append(order);
}
return statement.toString();
}
/**
* 根据查询条件拼接得到order by语句
* @param sorter 分页查询条件
* @return String
*/
public static String getOrderByStatement(Sorter sorter) {
String statement = getStatement(sorter);
if (StringUtils.isNotEmpty(statement)) {
return " order by " + statement;
} else {
return statement;
}
}
}
因为排序的字段名是驼峰命名,需要转为小写字母+下划线命名,转换的方法抽象到了StringUtils工具类中,代码如下。
public class StringUtils {
/**
* 判断字符串是否为null或""
* 符串为""或null返回true,否则返回false
* @param str 要判断的字符串
* @return boolean
*/
public static boolean isEmpty(String str) {
return str == null || str.isEmpty();
}
/**
* 判断字符串是否为""或null
* 符串为""或null返回false,否则返回true
* @param str 要判断的字符串
* @return boolean
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
* 判断字符串是否为null或""
* 符串为""或null返回true,否则返回false
* @param str 要判断的字符串
* @return boolean
*/
public static boolean isNullOrEmpty(String str) {
return str == null || str.isEmpty();
}
/**
* 检查字符串是否包含空白字符
* 如果不包含空格返回true,否则返回false
* @param str 需要比较的字符串
* @return boolean
*/
public boolean check(String str) {
// 去除空白字符后字符串的长度
int realLength = str.replaceAll("\\s", "").length();
int originalLength = str.length(); // 字符串原来的长度
return realLength == originalLength;
}
/**
* 根据当前时间生成UUID
* @return String
*/
public static String uuid() {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
LocalDateTime localDate = LocalDateTime.now();
return localDate.format(formatter);
}
/**
* 通过文件名获取文件类型
* @param fileName 文件名
*/
public static String getFileType(String fileName) {
// 得到文件名中最后一次出现"."的位置
int index = fileName.lastIndexOf('.');
return fileName.substring(index);
}
/**
* 获取文件名
* @param file MultipartFile对象
* @return String 由当前时间生成的新文件名
*/
public static String getFileName(MultipartFile file) {
// 得到上传文件的原始文件名
String filename = file.getOriginalFilename();
// 判断文件名是否为空
if (isNullOrEmpty(filename)) {
throw new RuntimeException("获取文件名失败!");
}
// 返回uuid.文件类型,如:20220618131456.jpg
return uuid() + getFileType(filename);
}
/**
* 功能:驼峰命名转下划线命名
* 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写
* @param str 待转换的字符串
* @return String
*/
public static String toLowerCase(String str) {
str = str.replaceAll("([a-z])([A-Z])", "$1_$2");
return str.toLowerCase();
}
/**
* 功能:下划线命名转驼峰命名
* 将下划线替换为空格,将字符串根据空格分割成数组,再将每个单词首字母大写
* @param str 待转换的字符串
* @return String
*/
private static String toUpperCase(String str) {
StringBuilder under= new StringBuilder();
str = str.toLowerCase().replace("_", " ");
String[] array = str.split(" ");
for (String s : array) {
String letter = s.substring(0, 1).toUpperCase() + s.substring(1);
under.append(letter);
}
return under.toString();
}
}
文章到此结束,感谢阅读~