用户自定义表格列
一、背景与问题
对于中后台系统,表格一般列会非常多、而且每个人关注的列又不一样,有些列中的文字太挤的话会换行,用户希望每个表格都可以自定义,并且在下次打开的时候还是保持原样,拆分下需求的问题:
- 1、列可以设置隐藏于显示
- 2、列可以设置自定义宽度
- 3、列可以设置自定义顺序
- 4、将以上自定义设置存入后端
二、架构与思想
;后端一件事:保存用户和表格列信息
2.1、前端分析
通过需求与整理的问题,再拆解下,前端三件事情:显示与隐藏、宽度、顺序,同时又需要每个table都要使用,那么前端就需要一个通用的组件来解决这三点。
在使用table
组件的时候,columns
属性中记录着所有的列信息,包含:列名、字段、顺序、宽度,所以这些信息可以直接使用。
初步定义如下:
- 组件名称为:
table-operator
- 组件``table-operator`中可以进行: 列的显示与隐藏、宽度、顺序
- 原来table的
columns
信息可以传递给table-operator
进行使用 table-operator
中修改完 “列的显示与隐藏、宽度、顺序” 之后,回传给原table的columns,用于显示
但是的需求是,“用户希望每次打开都是上次操作过的列信息”,那么怎么解决这个需求呢?
这个需求点说明,必须将 table-operator
中操作的列信息 存储到后端。有如下几点:
table-operator
有保存到后端的功能table-operator
有从后端获取列信息的功能table-operator
要有一个唯一table id
用于保存用户的“这个表”的列信息
2.2、后端分析
通过需求,了解到所有的操作都是前端进行的,后端只需记录 用户的表格列信息,那么有几个关键数据:
- 用户id
- 表格 table id
- 列信息 columns info
那么表结构有两种设计思路: 第一种,列铺开的形式,每个用户的一个表列设置 会对应多条数据记录
table 't_table_column' {
user_id, 用户id
table_id, 表格id
column_name, 列名
column_field, 列字段
column_sort, 列排序
column_show_flag, 列显示与隐藏
column_width 列宽
}
第二种,存储json的形式,每个用户的一个表列设置 会对应 一条 数据记录
table 't_table_column' {
user_id, 用户id
table_id, 表格id
columns, 所有列信息(json形式)
}
简单对比下
项目 | 优点 | 缺点 |
---|---|---|
铺开第一种 | 满足sql范式 | 数据量稍微多一点,因为一个系统中 table 会比较多 |
json第二种 | 数据量会少很多 | 不满足sql范式,字段用了json存储 |
最终选择了 第二种,具体原因:
- 1、 sql范式是为么满足 数据库的复杂功能,增删查改等,但是对于此功能,只需要存储,并不需要其他sql复杂语句
- 2、 不存在 任何的sql复杂操作
- 3、 无需将来在 navicat 端进行 数据查询排查问题
- 4、 数据量少点,数据库操作也不频繁
三、具体使用
1)在 src/components/support
顶级组件目录中有table-operator
组件目录;
2)在 src/constants/support/table-id-const.js
的table-id
的常量文件中 找到(或添加)新的 table 的唯一id
3)在具体的页面vue文件中,直接引入 table-operator
组件,引入第二步的 table-id
,如下:
template 中
<div class="smart-table-setting-block">
<TableOperator v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE" :refresh="ajaxQuery" />
</div>
<script> js 中
import TableOperator from '/@/components/support/table-operator/index.vue';
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
const columns = ref([
{
title: '企业名称',
dataIndex: 'enterpriseName',
minWidth: 180,
ellipsis: true,
},
....
....
]);
是不是很简单呢?
四、实现原理
4.1、 table-operator
第一步先定义通用组件 table-operator
,因为是通用组件,同时又是支撑support业务,定义到src/components/support
顶级组件目录中。
具体可以查看 table-operator
在table-operator
组件中有三个参数:
const props = defineProps({
// 表格列数组
modelValue: {
type: Array,
default: new Array(),
},
// 刷新表格函数
refresh: {
type: Function,
required: true,
},
// 表格id
tableId: {
type: Number,
require: true,
},
});
第一个组件参数modelValue
对应着原table中的 columns
字段,为了达到响应式,所以在原table中,必须将 columns
中定义为 ref
。
4.2、 table-id-const.js
根据上面的组件参数中有一个是 tableId
,表示表格id,并且要 前端全局唯一,所以呢,这也时候需要在顶级常量目录src/constants/support
中创建一个table-id
的常量文件,即table-id-const.js
。
//system系统功能表格初始化id
let systemInitTableId = 10000;
//support支撑功能表格初始化id
let supportInitTableId = 20000;
//业务表格初始化id
let businessOAInitTableId = 30000;
let businessERPInitTableId = 40000;
export const TABLE_ID_CONST = {
/**
* 业务
*/
BUSINESS: {
OA: {
NOTICE: businessOAInitTableId + 1, //通知公告
ENTERPRISE: businessOAInitTableId + 2, //企业信息
},
ERP: {
GOODS: businessERPInitTableId + 1, //商品管理
},
},
/**
* 系统
*/
SYSTEM: {
EMPLOYEE: systemInitTableId + 1, //员工
MENU: systemInitTableId + 2, //菜单
},
/**
* 支撑
*/
SUPPORT: {
CONFIG: supportInitTableId + 1, //参数配置
DICT: supportInitTableId + 2, //字典
SERIAL_NUMBER: supportInitTableId + 3, //单号
OPERATE_LOG: supportInitTableId + 4, //请求监控
HEART_BEAT: supportInitTableId + 5, //心跳
},
};
4.3、java代码
对于后端而言,采用的是第二种存储json的表结构,所以就比较简单了,就是普通的增删查改。
由于table-operator
是一个支撑业务,各个项目中都可能会用到,所以写到了 sa-base
项目中的 supoort包
;
具体可以查看 代码
联系我们
- 教育领域(高职院校数字化、就业创业大数据平台、继续教育平台;在线教育系统、视频直播、题库等,包含:医学、应急管理、成考、专升本等)
- 供应链领域(网络货运平台、大宗贸易进销存ERP、物流管理TMS、B2B电商、仓储WMS、AI提效等)
- 中医领域(诊所数字化管理、互联网医院、AI辅助诊疗、中医适宜技术、在线云问诊、空中药房等)
- AI+软件领域(软件定制外包、开源技术、数据大屏、国产化改造、技术升级换代、人员外包、技术顾问、技术培训等)
加微信: 卓大 拉你入群,一起学习 | 公众号 :六边形工程师 分享:赚钱、代码、生活 | 请 “1024创新实验室” 烩面里加肉 咖啡配胡辣汤,提神又饱腹 | 抖音 : 六边形工程师 直播:赚钱、代码、中医 |