利用周末时间,对已有的项目进行了升级,原来使用的是tkmybatis,改为mybatis plus。但是由于修改了返回数据的格式,前端页面字段排序失效了,需要刷新表格才会排序。页面效果如下
easyui的数据表格datagrid支持多字段排序,以及可以控制是否通过服务器排序,核心代码如下。
role_list.html文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>角色列表</title>
<link rel="stylesheet" href="/css/themes/icon.css"/>
<link rel="stylesheet" href="/css/themes/default/easyui.css" />
</head>
<body>
<table id="role_list"></table>
<script src="/js/public/public.js"></script>
<script src="/js/public/jquery.min.js"></script>
<script src="/js/public/jquery.easyui.min.js"></script>
<script src="/js/public/easyui-lang-zh_CN.js"></script>
<script src="/js/role_account/role_list.js"></script>
</body>
</html>
role_list.js文件:
$(document).ready(function() {
// 角色数据表格
$("#role_list").datagrid({
url: '/role_account/selectByPage',
method: 'post',
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();
}
}],
columns: [[
{field: 'id', title: '角色ID', align:"center", width:100, sortable: true},
{field: 'name', title: '角色名', align:"center", width:120},
{field: 'modelingId', title: '角色造型', align:"center", width: 80
, formatter: function(value, rowData, rowIndex) {
$.get("/role_modeling/selectNameAndImageById", {
id: value
}, function(result) {
$("#modeling_" + rowIndex).attr("src", result.image)
.attr("title", result.name).width(size);
});
return "<img id='modeling_" + rowIndex + "' />";
}
},
{field: 'grade', title: '等级', align: "center", sortable: true, width: 40
, 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 "<span title='" + group + "'>" + value+ "级</span>";
}
},
{field: 'score', title: '人物评分', align:"center", sortable: true, width: 50},
{field: 'schoolId', title: '门派', align:"center", width: 80
, formatter: function(value, rowData, rowIndex) {
$.get("/school/selectNameAndIconById", {
id: value
}, function(result) {
$("#school_" + rowIndex).attr("src", result.icon)
.attr("title", result.name).width(size);
});
return "<img id='school_" + rowIndex + "' />";
}
},
{field: 'jinbi', title: '金币', align:"center", sortable: true, width: 50},
{field: 'accountId', title: '账号', align:"center", width:200
, formatter: function(value, rowData, rowIndex) {
$.get("/account/selectAccountById", {
id: value
}, function(response) {
$("#account_" + rowIndex).html(response.data);
});
return "<div id='account_" + rowIndex + "'></div>";
}
},
{field: "lastUpdateTime", title: "最后一次修改", align: "center", width:125, sortable: true},
{field: 'right', title: '操作', align:"center"
, formatter: function(value, rowData, rowIndex) {
let link = '<a href="javascript:;" ' + 'onclick="handleDelete(' + rowData.id + ')">'
+ '<img title="删除" src="/css/themes/icons/delete.png" /></a>';
return link;
}
}
]]
});
});
其中multiSort设置为true表示允许多字段排序,remoteSort表示是否从服务器排序,设置为true,我们接下来在后台接口处理字段排序。
以上是easyui官网的截图,当多字段排序时,传递给后台的参数中通过逗号拼接。例如:通过评分score升序和等级grade降序排序时,后台接收到的参数为:
{
"sort": "score,grade"
"order": "asc,desc"
}
controller代码:
@RestController
@RequestMapping(path = "/role_account", produces="application/json; charset=utf-8")
public class RoleAccountController {
/**
* 分页条件查询角色列表
* @param pagerDTO 角色分页查询条件
* @return JsonPage<RoleAccount>
*/
@RequestMapping(path = "/selectByPage", method = RequestMethod.POST)
public JsonResult<PageResult<RoleAccount>> selectByPage(RoleAccountPagerDTO pagerDTO) {
return service.selectByPage(pagerDTO);
}
}
service代码:
@Slf4j
@Service
public class RoleAccountServiceImpl implements IRoleAccountService {
@Override
public JsonResult<PageResult<RoleAccount>> selectByPage(RoleAccountPagerDTO pagerDTO) {
Page<RoleAccount> page = new Page<>(pagerDTO.getPage(), pagerDTO.getRows());
QueryWrapper<RoleAccount> wrapper = new QueryWrapper<>();
wrapper.eq(!StringUtils.isEmpty(pagerDTO.getId()), "id", pagerDTO.getId());
wrapper.like(!StringUtils.isEmpty(pagerDTO.getName()), "name", pagerDTO.getName());
wrapper.eq(pagerDTO.getSchoolId() != null, "school_id", pagerDTO.getSchoolId());
wrapper.eq(pagerDTO.getModelingId() != null, "modeling_id", pagerDTO.getModelingId());
wrapper.eq(!StringUtils.isEmpty(pagerDTO.getAccountId()), "account_id", pagerDTO.getAccountId());
// 得到order by语句
String statement = BasePage.getOrderByStatement(pagerDTO);
log.info("得到的order by语句:{}", statement.isEmpty() ? "空" : statement);
wrapper.last(statement);
Page<RoleAccount> result = mapper.selectPage(page, wrapper);
return JsonResult.restPage(result);
}
}
mapper代码:
@Repository public interface RoleAccountMapper extends BaseMapper<RoleAccount> { }
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;
}
RoleAccountPagerDTO.java:
@Data
@EqualsAndHashCode(callSuper = true)
public class RoleAccountPagerDTO extends BasePage {
/**
* 角色id
*/
private String id;
/**
* 角色名
*/
private String name;
/**
* 等级
*/
private Integer grade;
/**
* 账号id
*/
private String accountId;
/**
* 门派id
*/
private Integer schoolId;
/**
* 角色造型id
*/
private Integer modelingId;
}
BasePage.java代码:
@Data
public class BasePage {
/**
* 页数
*/
private Integer page;
/**
* 每页记录数
*/
private Integer rows;
/**
* 排序字段
*/
private String sort;
/**
* 排序方式:asc/desc
*/
private String order;
/**
* 根据查询条件拼接得到order by语句
* @param basePage 分页查询条件
* @return String
*/
public static String getStatement(BasePage basePage) {
String sort;
String[] sortArray = {};
String[] orderArray = {};
String order = basePage.getOrder();
String sortColumn = basePage.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 basePage 分页查询条件
* @return String
*/
public static String getOrderByStatement(BasePage basePage) {
String statement = getStatement(basePage);
// 多字段排序
if (StringUtils.isNotEmpty(statement)) {
return " order by " + statement;
} else {
return statement;
}
}
}
因为排序的字段名是驼峰命名,需要转为小写字母+下划线命名,否则sql语句会报错,找不到对应字段。转换的方法抽象到了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();
}
}
好了,本章就分享那么多了,感谢您的阅读~