feat(table): 添加表格排序和选择功能支持

- 在KitPageArgs中新增OrderBy排序参数类,支持字段转下划线和排序绑定
- 修改SystemDictService.searchDict方法,集成排序参数处理逻辑
- 更新CuteDragTable和CuteSimpleTable组件,添加排序和选择功能
- 新增表格上方工具栏插槽和选择计数显示
- 优化前端表格组件的排序事件处理和数据刷新逻辑
This commit is contained in:
2026-01-30 19:08:01 +08:00
parent ae1de44b2c
commit 6b1045f0af
10 changed files with 323 additions and 52 deletions
@@ -6,6 +6,19 @@
--> -->
<template> <template>
<div> <div>
<el-row>
<el-col v-if="showSelect" :span="2" class="selection-box">
已选 <font class="selection-count">{{ crud.selection && crud.selection.length }}</font> 条
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:batchArea> 插槽,数据表格上方左侧 添加 批量操作入口 -->
<slot name="batchArea" />
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:toolArea> 插槽,数据表格上方右侧 添加 工具入口,比如导出 -->
<slot name="toolArea" />
</el-col>
</el-row>
<el-table <el-table
ref="table" ref="table"
v-loading="crud.loading" v-loading="crud.loading"
@@ -17,9 +30,12 @@
style="width: 100%;" style="width: 100%;"
:height="height" :height="height"
:max-height="height" :max-height="height"
highlight-current-row
highlight-selection-row
@sort-change="onTableSortChange"
@selection-change="onTableSelectionChange" @selection-change="onTableSelectionChange"
> >
<el-table-column v-if="mode === 'multi'" type="selection" width="55" /> <el-table-column v-if="showSelect" type="selection" width="55" />
<slot /> <slot />
<el-pagination <el-pagination
v-if="paging" v-if="paging"
@@ -60,10 +76,10 @@ export default {
required: false, required: false,
default: null default: null
}, },
mode: { showSelect: {
type: String, type: Boolean,
required: false, required: false,
default: 'none' default: false
}, },
paging: { paging: {
type: Boolean, type: Boolean,
@@ -95,7 +111,9 @@ export default {
console.log('on-page-change', currentPage, pageSize) console.log('on-page-change', currentPage, pageSize)
// this.$emit('onPageChange', currentPage, pageSize, total) // this.$emit('onPageChange', currentPage, pageSize, total)
this.refresh() this.refresh()
} },
orderBy: '',
selection: []
} }
} }
}, },
@@ -109,6 +127,8 @@ export default {
}, },
methods: { methods: {
refresh() { refresh() {
this.crud.orderBy = ''
this.crud.selection = []
this.initData() this.initData()
this.initDragTable() this.initDragTable()
}, },
@@ -118,6 +138,10 @@ export default {
if (this.paramsTransform) { if (this.paramsTransform) {
params = this.paramsTransform(this.pageProps) params = this.paramsTransform(this.pageProps)
} }
// 排序字段
if (this.crud.orderBy) {
params.orderBy = this.crud.orderBy
}
if (this.fetch) { if (this.fetch) {
try { try {
this.crud.loading = true this.crud.loading = true
@@ -134,14 +158,37 @@ export default {
this.crud.dataSource = response.content this.crud.dataSource = response.content
} }
return response return response
} catch (e) {
console.error('CuteDragTable请求远程数据异常', e)
this.pageProps.total = 0
this.crud.dataSource = []
} finally { } finally {
this.crud.loading = false this.crud.loading = false
} }
} }
}, },
onTableSelectionChange(selection) { onTableSelectionChange(selection) {
this.crud.selection = selection
this.$emit('selection-change', selection) this.$emit('selection-change', selection)
}, },
getDataSource() {
return this.crud.dataSource
},
onTableSortChange(sortProps) {
const prop = sortProps.prop
const order = sortProps.order
let result
if (order === 'ascending') {
result = { column: prop, orderType: 'asc' }
} else if (order === 'descending') {
result = { column: prop, orderType: 'desc' }
} else {
result = { column: prop, orderType: 'desc' }
}
// this.$emit('order-change', result)
this.crud.orderBy = result
this.refresh()
},
initDragTable() { initDragTable() {
const that = this const that = this
const table = that.$refs.table.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0] const table = that.$refs.table.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
@@ -163,11 +210,24 @@ export default {
data.forEach((item, index) => { data.forEach((item, index) => {
item.orderNum = index + 1 item.orderNum = index + 1
}) })
},
getDataSource() {
return this.crud.dataSource
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.selection-box {
text-align: left;
font-size: 12px;
padding-left: 10px;
min-height: 26.7px;
max-height: 26.7px;
padding-top: 7px;
}
.selection-count {
color: $menuActiveText;
}
</style>
@@ -6,6 +6,19 @@
--> -->
<template> <template>
<div> <div>
<el-row>
<el-col v-if="showSelect" :span="2" class="selection-box">
已选 <font class="selection-count">{{ crud.selection && crud.selection.length }}</font> 条
</el-col>
<el-col :span="11" style="text-align: left">
<!-- 通过 <template v-slot:batchArea> 插槽,数据表格上方左侧 添加 批量操作入口 -->
<slot name="batchArea" />
</el-col>
<el-col :span="11" style="text-align: right">
<!-- 通过 <template v-slot:toolArea> 插槽,数据表格上方右侧 添加 工具入口,比如导出 -->
<slot name="toolArea" />
</el-col>
</el-row>
<el-table <el-table
ref="table" ref="table"
v-loading="crud.loading" v-loading="crud.loading"
@@ -17,9 +30,12 @@
style="width: 100%;" style="width: 100%;"
:height="height" :height="height"
:max-height="height" :max-height="height"
highlight-current-row
highlight-selection-row
@sort-change="onTableSortChange"
@selection-change="onTableSelectionChange" @selection-change="onTableSelectionChange"
> >
<el-table-column v-if="mode === 'multi'" type="selection" width="55" /> <el-table-column v-if="showSelect" type="selection" width="55" />
<slot /> <slot />
</el-table> </el-table>
<el-pagination <el-pagination
@@ -60,10 +76,10 @@ export default {
required: false, required: false,
default: null default: null
}, },
mode: { showSelect: {
type: String, type: Boolean,
required: false, required: false,
default: 'none' default: false
}, },
paging: { paging: {
type: Boolean, type: Boolean,
@@ -100,7 +116,9 @@ export default {
console.log('on-page-change', currentPage, pageSize) console.log('on-page-change', currentPage, pageSize)
// this.$emit('onPageChange', currentPage, pageSize, total) // this.$emit('onPageChange', currentPage, pageSize, total)
this.refresh() this.refresh()
} },
orderBy: '',
selection: []
} }
} }
}, },
@@ -117,6 +135,8 @@ export default {
}, },
methods: { methods: {
refresh() { refresh() {
this.crud.orderBy = ''
this.crud.selection = []
this.initData() this.initData()
}, },
async initData() { async initData() {
@@ -125,6 +145,10 @@ export default {
if (this.paramsTransform) { if (this.paramsTransform) {
params = this.paramsTransform(this.pageProps) params = this.paramsTransform(this.pageProps)
} }
// 排序字段
if (this.crud.orderBy) {
params.orderBy = this.crud.orderBy
}
if (this.fetch) { if (this.fetch) {
try { try {
this.crud.loading = true this.crud.loading = true
@@ -141,15 +165,55 @@ export default {
this.crud.dataSource = response.content this.crud.dataSource = response.content
} }
return response return response
} catch (e) {
console.error('CuteSimpleTable请求远程数据异常', e)
this.pageProps.total = 0
this.crud.dataSource = []
} finally { } finally {
this.crud.loading = false this.crud.loading = false
} }
} }
}, },
onTableSelectionChange(selection) { onTableSelectionChange(selection) {
this.crud.selection = selection
this.$emit('selection-change', selection) this.$emit('selection-change', selection)
},
getDataSource() {
return this.crud.dataSource
},
onTableSortChange(sortProps) {
const prop = sortProps.prop
const order = sortProps.order
let result
if (order === 'ascending') {
result = { column: prop, orderType: 'asc' }
} else if (order === 'descending') {
result = { column: prop, orderType: 'desc' }
} else {
result = { column: prop, orderType: 'desc' }
}
// this.$emit('order-change', result)
this.crud.orderBy = result
this.refresh()
} }
} }
} }
</script> </script>
<style lang="scss" scoped>
@import "~@/assets/styles/variables.scss";
.selection-box {
text-align: left;
font-size: 12px;
padding-left: 10px;
min-height: 26.7px;
max-height: 26.7px;
padding-top: 7px;
}
.selection-count {
color: $menuActiveText;
}
</style>
@@ -9,6 +9,7 @@
label-position="right" label-position="right"
label-width="80px" label-width="80px"
:rules="form.rules" :rules="form.rules"
size="mini"
> >
<el-form-item label="模糊查询" prop="blurry"> <el-form-item label="模糊查询" prop="blurry">
<el-input v-model="form.model.blurry" clearable /> <el-input v-model="form.model.blurry" clearable />
@@ -24,9 +25,9 @@
<!-- params-transform: 组装查询参数 --> <!-- params-transform: 组装查询参数 -->
<!-- responseTransform: 组装表格对象。对响应结果做处理 --> <!-- responseTransform: 组装表格对象。对响应结果做处理 -->
<!-- primary-key: 主键 --> <!-- primary-key: 主键 -->
<!-- data-source: 数据源。当data-source不为空时,以data-source的数据为主 --> <!-- showSelect: 是否多选。不传默认false,传true为多选 -->
<!-- mode: 模式。不传默认,传multi为多选 -->
<!-- @selection-change: 当且仅当mode为multi时启用 --> <!-- @selection-change: 当且仅当mode为multi时启用 -->
<!-- @order-change: 当排序字段被单击,el-table-column 需添加 sortable="custom" 属性 -->
<cute-drag-table <cute-drag-table
ref="instance" ref="instance"
:fetch="curd.fetch" :fetch="curd.fetch"
@@ -9,6 +9,7 @@
label-position="right" label-position="right"
label-width="80px" label-width="80px"
:rules="form.rules" :rules="form.rules"
size="mini"
> >
<el-form-item label="模糊查询" prop="blurry"> <el-form-item label="模糊查询" prop="blurry">
<el-input v-model="form.model.blurry" clearable /> <el-input v-model="form.model.blurry" clearable />
@@ -28,18 +29,26 @@
<!-- params-transform: 组装查询参数 --> <!-- params-transform: 组装查询参数 -->
<!-- responseTransform: 组装表格对象。对响应结果做处理 --> <!-- responseTransform: 组装表格对象。对响应结果做处理 -->
<!-- primary-key: 主键 --> <!-- primary-key: 主键 -->
<!-- mode: 模式。不传默认,传multi为多选 --> <!-- showSelect: 是否多选。不传默认false,传true为多选 -->
<!-- @selection-change: 当且仅当mode为multi时启用 --> <!-- @selection-change: 当且仅当mode为multi时启用 -->
<!-- @order-change: 当排序字段被单击,el-table-column 需添加 sortable="custom" 属性 -->
<cute-simple-table <cute-simple-table
ref="instance" ref="instance"
:fetch="curd.fetch" :fetch="curd.fetch"
:params-transform="curd.paramsTransform" :params-transform="curd.paramsTransform"
primary-key="id" primary-key="id"
:page-props="curd.pageProps" :page-props="curd.pageProps"
show-select
> >
<template v-slot:batchArea>
<cute-button type="primary">批量绑定</cute-button>
</template>
<template v-slot:toolArea>
<cute-button type="primary">导出</cute-button>
</template>
<el-table-column prop="name" label="名称" /> <el-table-column prop="name" label="名称" />
<el-table-column prop="description" label="描述" /> <el-table-column prop="description" label="描述" />
<el-table-column prop="createTime" label="创建时间" :formatter="FormatRowDateTimeStr" /> <el-table-column prop="createTime" label="创建时间" sortable="custom" :formatter="FormatRowDateTimeStr" />
<el-table-column prop="createBy" label="创建人" /> <el-table-column prop="createBy" label="创建人" />
<el-table-column label="操作" width="150" min-width="150" fixed="right"> <el-table-column label="操作" width="150" min-width="150" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
@@ -50,7 +59,13 @@
</template> </template>
</el-table-column> </el-table-column>
</cute-simple-table> </cute-simple-table>
<cute-form-dialog ref="dialogForm" :model="createFormModel" :rules="createFormRules" title="演示:表单对话框" @submit="onDialogFormSubmit"> <cute-form-dialog
ref="dialogForm"
:model="createFormModel"
:rules="createFormRules"
title="演示:表单对话框"
@submit="onDialogFormSubmit"
>
<el-form-item label="活动名称" prop="name" label-width="100px"> <el-form-item label="活动名称" prop="name" label-width="100px">
<el-input v-model="createFormModel.name" placeholder="请输入" style="width: 100%" /> <el-input v-model="createFormModel.name" placeholder="请输入" style="width: 100%" />
</el-form-item> </el-form-item>
@@ -61,7 +76,14 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
</cute-form-dialog> </cute-form-dialog>
<cute-form-drawer ref="drawerFrom" :model="createFormModel" :rules="createFormRules" title="演示:表单抽屉" @submit="onDrawerFormSubmit"> <cute-form-drawer
ref="drawerFrom"
:model="createFormModel"
:rules="createFormRules"
title="演示:表单抽屉"
width="45%"
@submit="onDrawerFormSubmit"
>
<el-form-item label="活动名称" prop="name" label-width="100px"> <el-form-item label="活动名称" prop="name" label-width="100px">
<el-input v-model="createFormModel.name" placeholder="请输入" style="width: 100%" /> <el-input v-model="createFormModel.name" placeholder="请输入" style="width: 100%" />
</el-form-item> </el-form-item>
@@ -71,6 +93,12 @@
<el-option label="区域二" value="beijing" /> <el-option label="区域二" value="beijing" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="活动模式" prop="modeList" label-width="100px">
<cute-transfer v-model="createFormModel.modeList" :data-source="modeDataSource">
<el-table-column prop="name" label="姓名" />
<el-table-column prop="description" label="备注" />
</cute-transfer>
</el-form-item>
</cute-form-drawer> </cute-form-drawer>
</div> </div>
</template> </template>
@@ -81,12 +109,21 @@ import DictService from '@/api/system/dict'
import CuteFormDialog from '@/views/components/dev/CuteFormDialog' import CuteFormDialog from '@/views/components/dev/CuteFormDialog'
import CuteFormDrawer from '@/views/components/dev/CuteFormDrawer' import CuteFormDrawer from '@/views/components/dev/CuteFormDrawer'
import { FormatRowDateTimeStr } from '@/utils/CsUtil' import { FormatRowDateTimeStr } from '@/utils/CsUtil'
import CuteButton from '@/views/components/dev/CuteButton.vue'
import CuteTransfer from '@/views/components/dev/CuteTransfer.vue'
export default { export default {
name: 'CuteSimpleTableDemo', name: 'CuteSimpleTableDemo',
components: { CuteFormDrawer, CuteFormDialog, CuteSimpleTable }, components: { CuteTransfer, CuteButton, CuteFormDrawer, CuteFormDialog, CuteSimpleTable },
data() { data() {
return { return {
modeDataSource: [
{ id: 1, name: '小明', description: '小明牛P' },
{ id: 2, name: '小明', description: '小明牛P' },
{ id: 3, name: '小明', description: '小明牛P' },
{ id: 4, name: '小明', description: '小明牛P' },
{ id: 5, name: '小明', description: '小明牛P' }
],
form: { form: {
model: { model: {
blurry: '' blurry: ''
@@ -137,7 +174,8 @@ export default {
}, },
createFormModel: { createFormModel: {
name: '', name: '',
region: '' region: '',
modeList: []
}, },
createFormRules: { createFormRules: {
name: [ name: [
@@ -15,13 +15,13 @@
*/ */
package cn.odboy.base; package cn.odboy.base;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor; import lombok.*;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* 数据分页参数 * 数据分页参数
@@ -32,7 +32,8 @@ import lombok.NoArgsConstructor;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class KitPageArgs<T> implements Serializable { @EqualsAndHashCode(callSuper = false)
public class KitPageArgs<T> extends KitObject {
@NotNull(message = "参数page不能为空") @NotNull(message = "参数page不能为空")
@Min(value = 1, message = "参数page最小值为1") @Min(value = 1, message = "参数page最小值为1")
@@ -43,4 +44,46 @@ public class KitPageArgs<T> implements Serializable {
@ApiModelProperty(value = "每页数据量", example = "10") @ApiModelProperty(value = "每页数据量", example = "10")
private Integer size; private Integer size;
private T args; private T args;
@ApiModelProperty(value = "排序参数")
private OrderBy orderBy;
@Setter
public static class OrderBy extends KitObject {
/**
* 排序列名称
*/
private String column;
/**
* 排序方式
*/
private String orderType;
/**
* 字段属性转下划线
*
* @return /
*/
public String getColumn() {
return StrUtil.toUnderlineCase(this.column);
}
/**
* 是否顺序排序
*
* @return /
*/
public boolean isAsc() {
return "asc".equals(this.orderType);
}
/**
* 绑定 QueryWrapper,应用排序条件
*
* @param wrapper QueryWrapper<T>
*/
public <T> void bindWrapper(QueryWrapper<T> wrapper) {
wrapper.orderBy(true, this.isAsc(), this.getColumn());
}
}
} }
@@ -25,6 +25,10 @@ import cn.odboy.system.service.SystemDictService;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import java.util.List;
import java.util.Set;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -34,9 +38,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set;
@RestController @RestController
@Api(tags = "系统:字典管理") @Api(tags = "系统:字典管理")
@@ -67,7 +68,7 @@ public class SystemDictController {
@PreAuthorize("@el.check('dict:list')") @PreAuthorize("@el.check('dict:list')")
public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs(@Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) { public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs(@Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) {
Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return ResponseEntity.ok(systemDictService.searchDict(pageArgs.getArgs(), page)); return ResponseEntity.ok(systemDictService.searchDict(pageArgs.getArgs(), page, pageArgs.getOrderBy()));
} }
@OperationLog @OperationLog
@@ -17,6 +17,7 @@ package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.system.dal.dataobject.SystemDictTb; import cn.odboy.system.dal.dataobject.SystemDictTb;
import cn.odboy.system.dal.model.export.SystemDictExportRowVo; import cn.odboy.system.dal.model.export.SystemDictExportRowVo;
@@ -28,11 +29,12 @@ import cn.odboy.util.KitBeanUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import jakarta.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -85,14 +87,19 @@ public class SystemDictService {
/** /**
* 分页查询 * 分页查询
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @param orderBy 排序参数
* @return / * @return /
*/ */
public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page) { public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page, KitPageArgs.OrderBy orderBy) {
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>(); QueryWrapper<SystemDictTb> wrapper = new QueryWrapper<>();
this.injectQueryParams(args, wrapper); if (orderBy != null) {
Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, wrapper); orderBy.bindWrapper(wrapper);
}
LambdaQueryWrapper<SystemDictTb> lambda = wrapper.lambda();
this.injectQueryParams(args, lambda);
Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, lambda);
return KitPageUtil.toPage(selectPage); return KitPageUtil.toPage(selectPage);
} }
@@ -150,8 +157,10 @@ public class SystemDictService {
*/ */
private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) { private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) {
if (args != null) { if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemDictTb::getName, args.getBlurry()).or() wrapper.and(
.like(SystemDictTb::getDescription, args.getBlurry())); StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemDictTb::getName, args.getBlurry()).or().like(SystemDictTb::getDescription, args.getBlurry())
);
} }
} }
} }
@@ -15,13 +15,15 @@
*/ */
package cn.odboy.base; package cn.odboy.base;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable; import java.io.Serializable;
import javax.validation.constraints.Min; import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.Data; import lombok.*;
import lombok.NoArgsConstructor;
/** /**
* 数据分页参数 * 数据分页参数
@@ -32,7 +34,8 @@ import lombok.NoArgsConstructor;
@Data @Data
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
public class KitPageArgs<T> implements Serializable { @EqualsAndHashCode(callSuper = false)
public class KitPageArgs<T> extends KitObject {
@NotNull(message = "参数page不能为空") @NotNull(message = "参数page不能为空")
@Min(value = 1, message = "参数page最小值为1") @Min(value = 1, message = "参数page最小值为1")
@@ -43,4 +46,46 @@ public class KitPageArgs<T> implements Serializable {
@ApiModelProperty(value = "每页数据量", example = "10") @ApiModelProperty(value = "每页数据量", example = "10")
private Integer size; private Integer size;
private T args; private T args;
@ApiModelProperty(value = "排序参数")
private OrderBy orderBy;
@Setter
public static class OrderBy extends KitObject {
/**
* 排序列名称
*/
private String column;
/**
* 排序方式
*/
private String orderType;
/**
* 字段属性转下划线
*
* @return /
*/
public String getColumn() {
return StrUtil.toUnderlineCase(this.column);
}
/**
* 是否顺序排序
*
* @return /
*/
public boolean isAsc() {
return "asc".equals(this.orderType);
}
/**
* 绑定 QueryWrapper,应用排序条件
*
* @param wrapper QueryWrapper<T>
*/
public <T> void bindWrapper(QueryWrapper<T> wrapper) {
wrapper.orderBy(true, this.isAsc(), this.getColumn());
}
}
} }
@@ -67,7 +67,7 @@ public class SystemDictController {
@PreAuthorize("@el.check('dict:list')") @PreAuthorize("@el.check('dict:list')")
public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs(@Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) { public ResponseEntity<KitPageResult<SystemDictTb>> queryDictByArgs(@Validated @RequestBody KitPageArgs<SystemQueryDictArgs> pageArgs) {
Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize()); Page<SystemDictTb> page = new Page<>(pageArgs.getPage(), pageArgs.getSize());
return ResponseEntity.ok(systemDictService.searchDict(pageArgs.getArgs(), page)); return ResponseEntity.ok(systemDictService.searchDict(pageArgs.getArgs(), page, pageArgs.getOrderBy()));
} }
@OperationLog @OperationLog
@@ -17,6 +17,7 @@ package cn.odboy.system.service;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.odboy.base.KitPageArgs;
import cn.odboy.base.KitPageResult; import cn.odboy.base.KitPageResult;
import cn.odboy.system.dal.dataobject.SystemDictTb; import cn.odboy.system.dal.dataobject.SystemDictTb;
import cn.odboy.system.dal.model.export.SystemDictExportRowVo; import cn.odboy.system.dal.model.export.SystemDictExportRowVo;
@@ -28,10 +29,12 @@ import cn.odboy.util.KitBeanUtil;
import cn.odboy.util.KitPageUtil; import cn.odboy.util.KitPageUtil;
import cn.odboy.util.xlsx.KitExcelExporter; import cn.odboy.util.xlsx.KitExcelExporter;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -85,14 +88,19 @@ public class SystemDictService {
/** /**
* 分页查询 * 分页查询
* *
* @param args 条件 * @param args 条件
* @param page 分页参数 * @param page 分页参数
* @param orderBy 排序参数
* @return / * @return /
*/ */
public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page) { public KitPageResult<SystemDictTb> searchDict(SystemQueryDictArgs args, Page<SystemDictTb> page, KitPageArgs.OrderBy orderBy) {
LambdaQueryWrapper<SystemDictTb> wrapper = new LambdaQueryWrapper<>(); QueryWrapper<SystemDictTb> wrapper = new QueryWrapper<>();
this.injectQueryParams(args, wrapper); if (orderBy != null) {
Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, wrapper); orderBy.bindWrapper(wrapper);
}
LambdaQueryWrapper<SystemDictTb> lambda = wrapper.lambda();
this.injectQueryParams(args, lambda);
Page<SystemDictTb> selectPage = systemDictMapper.selectPage(page, lambda);
return KitPageUtil.toPage(selectPage); return KitPageUtil.toPage(selectPage);
} }
@@ -150,8 +158,10 @@ public class SystemDictService {
*/ */
private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) { private void injectQueryParams(SystemQueryDictArgs args, LambdaQueryWrapper<SystemDictTb> wrapper) {
if (args != null) { if (args != null) {
wrapper.and(StrUtil.isNotBlank(args.getBlurry()), c -> c.like(SystemDictTb::getName, args.getBlurry()).or() wrapper.and(
.like(SystemDictTb::getDescription, args.getBlurry())); StrUtil.isNotBlank(args.getBlurry()),
c -> c.like(SystemDictTb::getName, args.getBlurry()).or().like(SystemDictTb::getDescription, args.getBlurry())
);
} }
} }
} }