业务需求el-table 需要支持多列排序,后端排序。即就是在点击后重新发送请求,点击一列的排序,另一列的排序样式能够保留,但是el-table默认是单列排序。
页面
<el-row>
<el-table id="tableData" :data="tableData" ref="table" overflow:auto :fit="true" class="fit_tbl" :border=true
:row-style="{height:'20px'}" :cell-style="{padding:'0px'}" style="font-size: 10px" v-loading="tblLoading"
:header-cell-class-name="handleHeaderClass"
@header-click="handleHeaderCLick"
@sort-change="handleTableSort">
<el-table-column prop="reportPeriod" width="100" label="月份" align="center" key="2">el-table-column>
<el-table-column sortable="custom" prop="indName" width="100" label="所属行业" align="center" key="3">el-table-column>
<el-table-column prop="stockCode" width="100" label="股票代码" align="center" key="4">el-table-column>
<el-table-column sortable="custom" prop="stockName" width="100" label="股票名称" align="center" key="5">el-table-column>
<el-table-column sortable="custom" prop="organName" width="100" label="券商名称" align="center" key="6">el-table-column>
<el-table-column prop="authorName" width="150" label="研究员" align="center" key="7">el-table-column>
<el-table-column prop="recoReason" label="推荐原因" align="left" key="8">el-table-column>
el-table>
<el-pagination
:page-size=size
:page-sizes = " [10, 20, 30, 40, 50, 100] "
@current-change="handleSearch()"
@size-change = "handleSizeChange"
:current-page.sync="page"
layout="total, sizes, prev, pager, next, jumper"
:total="tmpTotal">
el-pagination>
el-row>
/**
* @header-click="handleHeaderCLick"
* 点击表头文字触发的监听器
*
* @sort-change="handleTableSort"
* 点击表头排序标签触发定时器
*/
data : {
tmpTotal: 0,
tableData: [],
tblLoading: false,
ordersList: [],
},
// 上面缺点是只能通过点击表头切换排序状态,点击小三角排序不会触发,处理sort-change事件和点击表头一样,列表排序
handleTableSort({ column }) {
// 如果表格的sortable属性不等于custom说明是不需要排序的,直接返回
if (column.sortable !== 'custom') {
return;
}
if (!column.multiOrder) {
// 如果multiOrder为空说明还没有排序,设置默认升序
column.multiOrder = 'descending'
} else if (column.multiOrder === 'descending') {
// 如果当前multiOrder为升序,再次点击设置为降序
column.multiOrder = 'ascending'
} else {
// 如果当前multiOrder为降序,再次点击设置为不排序
column.multiOrder = ''
}
this.handleOrderChange(column.property, column.multiOrder)
},
/**
* 向数组ordersList中存放或修改表头排序信息
*
* @param orderColumn
* @param orderState
*/
handleOrderChange (orderColumn, orderState) {
let result = this.ordersList.find(e => e.orderColumn === orderColumn)
if (result) {
result.orderState = orderState
} else {
this.ordersList.push({
orderColumn: orderColumn,
orderState: orderState
})
}
// 调接口查询,在传参的时候把ordersList进行处理成后端想要的格式
this.handleSearch()
},
/**
* 向后端发送请求,获取排序后的数据
*/
handleSearch: function () {
vue.tblLoading = true;
let orderObject = {};
// 处理存放要排序的表头信息
if (!this.isEmpty(this.ordersList)) {
for (let i = 0; i < this.ordersList.length; i++) {
let temp = this.ordersList[i];
if (temp.orderState === "ascending") {
// 降序
orderObject[temp.orderColumn] = "asc";
}
if (temp.orderState === "descending") {
// 升序
orderObject[temp.orderColumn] = "desc";
}
}
}
// 请求发送
ais_ajax({
url:'/analysis/inv-fd/goldStock/queryGoldStockInfo',
data : {
orderObject: JSON.stringify(orderObject)
},
type:'post',
successFn:function(data){
vue.tmpTotal = data.total;
vue.tableData = data.rows;
vue.tblLoading = false;
}
});
},
后端处理
@RequestMapping(method = RequestMethod.POST, value = "queryGoldStockInfo")
public String queryGoldStockInfo(HttpServletRequest req) {
String orderObject = this.getStrParam(req, "orderObject");
int page = this.getIntParam(req, "page", 1);
int size = this.getIntParam(req, "size", 10);
// 解析排序数据,手动拼接排序的sql
StringBuilder sb = new StringBuilder();
JSONObject object = JSON.parseObject(orderObject);
if (!object.isEmpty()) {
if (object.containsKey("organName")) {
sb.append("organName ").append(object.getString("organName")).append(",");
}
if (object.containsKey("indName")) {
sb.append("indName ").append(object.getString("indName")).append(",");
}
if (object.containsKey("stockName")) {
sb.append("stockName ").append(object.getString("stockName"));
}
orderList = sb.toString();
if (orderList.lastIndexOf(",") == (orderList.length() - 1)) {
orderList = orderList.substring(0, orderList.lastIndexOf(","));
}
}
Map<String, Object> map = new HashMap<>();
map.put("orderList", orderList);
PageInfo<GogoalGoldStockVO> list = gogoalGoldStockService.queryGoldStockInfo(map, page, size);
List<GogoalGoldStockVO> all = list.getList();
JSONObject obj = new JSONObject();
JSONArray rows = (JSONArray) JSONArray.toJSON(all);
obj.put("rows", rows);
obj.put("total", list.getTotal());
return obj.toJSONString();
}
XML文件,其中 orderList 就是手动拼接的sql
注意:这里要用sql注入的方式(${ })将orderList填充到查询语句的最后,不然这里的orderList会先被解析再填充
<select id="queryGoldStockInfo" resultType="com.analysis.investment.foundation.db.mybatis.entity.ods.GogoalGoldStockVO">
select a.stock_code stockCode, a.stock_name stockName, a.reco_reason recoReason, a.report_year reportYear,
a.report_period reportPeriod, a.organ_name organName, a.author_name authorName, b.ind_name indName
from ais_inv_ods.gogoal_gs_rpt_goldstock a
inner join t_market_stockind b on (a.stock_code = b.gpdm)
<where>
<if test="year != null and year != ''">
AND a.report_year = #{year}
if>
<if test="month != null and month != ''">
AND a.report_period = #{month}
if>
<if test="broker != null and broker != ''">
AND a.organ_name = #{broker}
if>
<if test="stock != null and stock != ''">
AND a.stock_code = #{stock}
if>
<if test="industry != null and industry != ''">
AND b.ind_index_code = #{industry}
if>
where>
<if test="orderList != null and orderList != ''">
order by ${orderList}
if>
select>