2023-07-06 20:59:22 +08:00
|
|
|
|
import EnumValue from '@/common/Enum';
|
2024-05-13 19:55:43 +08:00
|
|
|
|
import { formatDate } from '@/common/utils/format';
|
2024-02-29 22:12:50 +08:00
|
|
|
|
import { getValueByPath } from '@/common/utils/object';
|
2023-06-29 00:40:42 +08:00
|
|
|
|
import { getTextWidth } from '@/common/utils/string';
|
2023-06-28 21:35:03 +08:00
|
|
|
|
|
|
|
|
|
|
export class TableColumn {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 属性字段
|
|
|
|
|
|
*/
|
|
|
|
|
|
prop: string;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 显示表头
|
|
|
|
|
|
*/
|
|
|
|
|
|
label: string;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 是否自动计算宽度
|
|
|
|
|
|
*/
|
|
|
|
|
|
autoWidth: boolean = true;
|
|
|
|
|
|
|
2023-06-29 00:40:42 +08:00
|
|
|
|
/**
|
2023-07-06 20:59:22 +08:00
|
|
|
|
* 自动计算宽度时,累加该值(可能列值会进行转换 如添加图标等,宽度需要比计算出来的更宽些)
|
2023-06-29 00:40:42 +08:00
|
|
|
|
*/
|
|
|
|
|
|
addWidth: number = 0;
|
|
|
|
|
|
|
2023-07-06 20:59:22 +08:00
|
|
|
|
/**
|
2023-06-28 21:35:03 +08:00
|
|
|
|
* 最小宽度
|
|
|
|
|
|
*/
|
|
|
|
|
|
minWidth: number | string;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2024-02-29 22:12:50 +08:00
|
|
|
|
* 是否为插槽,若slotName为空则插槽名为prop属性名
|
2023-06-28 21:35:03 +08:00
|
|
|
|
*/
|
2023-07-01 21:24:07 +08:00
|
|
|
|
slot: boolean = false;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
|
2024-02-29 22:12:50 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 插槽名,
|
|
|
|
|
|
*/
|
|
|
|
|
|
slotName: string = '';
|
|
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
showOverflowTooltip: boolean = true;
|
|
|
|
|
|
|
|
|
|
|
|
sortable: boolean = false;
|
|
|
|
|
|
|
2023-07-06 20:59:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 官方:对应列的类型。 如果设置了selection则显示多选框;
|
|
|
|
|
|
* 如果设置了 index 则显示该行的索引(从 1 开始计算);
|
|
|
|
|
|
*
|
|
|
|
|
|
* 新增 tag类型,用于枚举值转换后用tag进行展示
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
2023-06-28 21:35:03 +08:00
|
|
|
|
type: string;
|
|
|
|
|
|
|
2023-07-06 20:59:22 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 类型展示需要的额外参数,如枚举转换的EnumValue值等
|
|
|
|
|
|
*/
|
|
|
|
|
|
typeParam: any;
|
|
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
width: number | string;
|
|
|
|
|
|
|
|
|
|
|
|
fixed: any;
|
|
|
|
|
|
|
2023-07-06 20:59:22 +08:00
|
|
|
|
align: string = 'left';
|
2023-06-28 21:35:03 +08:00
|
|
|
|
|
2023-06-29 11:49:14 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 指定格式化函数对原始值进行格式化,如时间格式化等
|
|
|
|
|
|
* param1: data, param2: prop
|
|
|
|
|
|
*/
|
2023-07-06 20:59:22 +08:00
|
|
|
|
formatFunc: Function;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
|
2023-06-29 11:49:14 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 是否显示该列
|
|
|
|
|
|
*/
|
2023-07-06 20:59:22 +08:00
|
|
|
|
show: boolean = true;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
|
2023-07-20 22:41:13 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 是否展示美化按钮(主要用于美化json文本等)
|
|
|
|
|
|
*/
|
|
|
|
|
|
isBeautify: boolean = false;
|
|
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
constructor(prop: string, label: string) {
|
|
|
|
|
|
this.prop = prop;
|
|
|
|
|
|
this.label = label;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-29 11:49:14 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 获取该列在指定行数据中的值
|
|
|
|
|
|
* @param rowData 该行对应的数据
|
|
|
|
|
|
* @returns 该列对应的值
|
|
|
|
|
|
*/
|
|
|
|
|
|
getValueByData(rowData: any) {
|
|
|
|
|
|
if (this.formatFunc) {
|
|
|
|
|
|
return this.formatFunc(rowData, this.prop);
|
|
|
|
|
|
}
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return getValueByPath(rowData, this.prop);
|
2023-06-29 11:49:14 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
static new(prop: string, label: string): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
return new TableColumn(prop, label);
|
2023-06-28 21:35:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-02 17:06:00 +08:00
|
|
|
|
noShowOverflowTooltip(): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.showOverflowTooltip = false;
|
2023-07-02 17:06:00 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
setMinWidth(minWidth: number | string): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.minWidth = minWidth;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
this.autoWidth = false;
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-29 00:40:42 +08:00
|
|
|
|
setAddWidth(addWidth: number): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.addWidth = addWidth;
|
2023-06-29 00:40:42 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-05 22:06:32 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 居中对齐
|
|
|
|
|
|
* @returns this
|
|
|
|
|
|
*/
|
|
|
|
|
|
alignCenter(): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.align = 'center';
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 使用标签类型展示该列(用于枚举值友好展示)
|
2023-12-18 22:39:32 +08:00
|
|
|
|
* @param param 枚举对象, 如AccountStatusEnum
|
2023-07-06 20:59:22 +08:00
|
|
|
|
* @returns this
|
|
|
|
|
|
*/
|
|
|
|
|
|
typeTag(param: any): TableColumn {
|
|
|
|
|
|
this.type = 'tag';
|
|
|
|
|
|
this.typeParam = param;
|
2023-07-05 22:06:32 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-20 22:41:13 +08:00
|
|
|
|
typeText(): TableColumn {
|
|
|
|
|
|
this.type = 'text';
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
typeJson(): TableColumn {
|
|
|
|
|
|
this.type = 'jsonText';
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-01 21:24:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 标识该列为插槽
|
|
|
|
|
|
* @returns this
|
|
|
|
|
|
*/
|
2024-02-29 22:12:50 +08:00
|
|
|
|
isSlot(slotName: string = ''): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.slot = true;
|
2024-02-29 22:12:50 +08:00
|
|
|
|
this.slotName = slotName;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-29 11:49:14 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 设置该列的格式化回调函数
|
|
|
|
|
|
* @param func 格式化回调函数(参数为 -> data: 该行对应的数据,prop: 该列对应的prop属性值)
|
2023-07-06 20:59:22 +08:00
|
|
|
|
* @returns
|
2023-06-29 11:49:14 +08:00
|
|
|
|
*/
|
2023-06-28 21:35:03 +08:00
|
|
|
|
setFormatFunc(func: Function): TableColumn {
|
|
|
|
|
|
this.formatFunc = func;
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 为时间字段,则使用默认时间格式函数
|
|
|
|
|
|
* @returns this
|
|
|
|
|
|
*/
|
|
|
|
|
|
isTime(): TableColumn {
|
2023-06-29 11:49:14 +08:00
|
|
|
|
this.setFormatFunc((data: any, prop: string) => {
|
2024-05-13 19:55:43 +08:00
|
|
|
|
return formatDate(getValueByPath(data, prop));
|
2023-07-06 20:59:22 +08:00
|
|
|
|
});
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 标识该列枚举类,需进行枚举值转换
|
|
|
|
|
|
* @returns this
|
|
|
|
|
|
*/
|
|
|
|
|
|
isEnum(enums: any): TableColumn {
|
|
|
|
|
|
this.setFormatFunc((data: any, prop: string) => {
|
2024-02-29 22:12:50 +08:00
|
|
|
|
return EnumValue.getLabelByValue(enums, getValueByPath(data, prop));
|
2023-07-06 20:59:22 +08:00
|
|
|
|
});
|
2023-06-28 21:35:03 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fixedRight(): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.fixed = 'right';
|
2023-06-28 21:35:03 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fixedLeft(): TableColumn {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
this.fixed = 'left';
|
2023-06-28 21:35:03 +08:00
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-07-20 22:41:13 +08:00
|
|
|
|
canBeautify(): TableColumn {
|
|
|
|
|
|
this.isBeautify = true;
|
|
|
|
|
|
return this;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
/**
|
2023-06-29 11:49:14 +08:00
|
|
|
|
* 自动计算最小宽度
|
2023-06-28 21:35:03 +08:00
|
|
|
|
* @param str 字符串
|
|
|
|
|
|
* @param tableData 表数据
|
|
|
|
|
|
* @param label 表头label也参与宽度计算
|
|
|
|
|
|
* @returns 列宽度
|
|
|
|
|
|
*/
|
2023-06-29 11:49:14 +08:00
|
|
|
|
autoCalculateMinWidth = (tableData: any) => {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
const prop = this.prop;
|
|
|
|
|
|
const label = this.label;
|
2023-06-29 11:49:14 +08:00
|
|
|
|
|
2023-06-28 21:35:03 +08:00
|
|
|
|
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
2023-06-29 00:40:42 +08:00
|
|
|
|
return 0;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
}
|
2023-06-29 11:49:14 +08:00
|
|
|
|
|
2023-07-06 20:59:22 +08:00
|
|
|
|
let maxWidthText = '';
|
|
|
|
|
|
let maxWidthValue;
|
2023-06-29 11:49:14 +08:00
|
|
|
|
// 为了兼容formatFunc格式化回调函数
|
2023-07-06 20:59:22 +08:00
|
|
|
|
let maxData;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
// 获取该列中最长的数据(内容)
|
|
|
|
|
|
for (let i = 0; i < tableData.length; i++) {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
let nowData = tableData[i];
|
2024-02-29 22:12:50 +08:00
|
|
|
|
let nowValue = getValueByPath(nowData, prop);
|
2023-06-29 11:49:14 +08:00
|
|
|
|
if (!nowValue) {
|
2023-06-28 21:35:03 +08:00
|
|
|
|
continue;
|
|
|
|
|
|
}
|
2023-06-29 11:49:14 +08:00
|
|
|
|
// 转为字符串比较长度
|
2023-07-06 20:59:22 +08:00
|
|
|
|
let nowText = nowValue + '';
|
2023-06-29 11:49:14 +08:00
|
|
|
|
if (nowText.length > maxWidthText.length) {
|
|
|
|
|
|
maxWidthText = nowText;
|
|
|
|
|
|
maxWidthValue = nowValue;
|
|
|
|
|
|
maxData = nowData;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2023-06-29 11:49:14 +08:00
|
|
|
|
if (this.formatFunc && maxWidthValue) {
|
2023-07-06 20:59:22 +08:00
|
|
|
|
maxWidthText = this.formatFunc(maxData, prop) + '';
|
2023-06-29 11:49:14 +08:00
|
|
|
|
}
|
2023-06-29 00:40:42 +08:00
|
|
|
|
// 需要加上表格的内间距等,视情况加
|
2023-06-29 11:49:14 +08:00
|
|
|
|
const contentWidth: number = getTextWidth(maxWidthText) + 30;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
// 获取label的宽度,取较大的宽度
|
2023-06-29 00:40:42 +08:00
|
|
|
|
const columnWidth: number = getTextWidth(label) + 60;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
const flexWidth: number = contentWidth > columnWidth ? contentWidth : columnWidth;
|
2023-06-29 11:49:14 +08:00
|
|
|
|
// 设置上限与累加需要额外增加的宽度
|
|
|
|
|
|
this.minWidth = (flexWidth > 400 ? 400 : flexWidth) + this.addWidth;
|
2023-06-28 21:35:03 +08:00
|
|
|
|
};
|
|
|
|
|
|
}
|