import { VNode, ComponentPublicInstance } from "vue"; import { BreakPoint, Responsive } from "@/components/Grid/interface"; // import { TableColumnCtx } from "element-plus/es/components/table/src/table-column/defaults"; import LjVxeTable from "@/components/LjVxeTable/index.vue"; import type { VxeColumnProps, VxeTablePropTypes } from "vxe-table"; import { cloneDeep } from "lodash-es"; import dayjs from "dayjs"; export interface EnumProps { label?: string; // 选项框显示的文字 value?: string | number | boolean | any[]; // 选项框值 disabled?: boolean; // 是否禁用此选项 tagType?: string; // 当 tag 为 true 时,此选择会指定 tag 显示类型 children?: EnumProps[]; // 为树形选择时,可以通过 children 属性指定子选项 [key: string]: any; } export type TypeProps = "index" | "checkbox" | "expand"; export type TypeFormat = | "yyyy-MM-dd" | "yyyy-MM-dd HH:mm:ss" | "yyyy-MM-dd HH:mm" | "MM/dd/yyyy" | "MM/dd" | "dd/MM/yyyy" | "yyyy/MM/dd" | "intNumber" | "cutNumber" | "cutNumber3" | "amountNumber" | "fixedNumber" | "percent"; export type SearchType = | "text" | "input" | "input-number" | "select" | "select-v2" | "tree-select" | "cascader" | "date-picker" | "time-picker" | "time-select" | "switch" | "slider" | "checkbox-group" | "radio-group" | "autocomplete"; export type SearchRenderScope = { searchParam: { [key: string]: any }; placeholder: string; clearable: boolean; options: EnumProps[]; data: EnumProps[]; status?: any; }; /** * @description 数据模型:搜索模块 */ export type SearchProps = { /** * @argument SearchType 当前项搜索框的类型 */ el?: SearchType; /** * @argument 搜索项参数,根据 element plus 官方文档来传递,该属性所有值会透传到组件 */ props?: any; key?: string; // 当搜索项 key 不为 prop 属性时,可通过 key 指定 order?: number; // 搜索项排序(从大到小) /** * @argument number 所占用的列数,默认为1列 */ span?: number; /** * @argument number 搜索字段左侧偏移列数 */ offset?: number; /** * @argument 搜索项默认值 */ defaultValue?: string | number | boolean | any[]; /** * @argument 自定义搜索内容渲染(tsx语法)用于渲染搜索,或basicinfoProps详情页编辑 */ render?: (scope: SearchRenderScope) => VNode; /** * @argument string 表单域标签的位置 */ labelPosition?: "left" | "right" | "top"; /** * @argument string 标签宽度 */ labelWidth?: string | number; /** * @description 是否可视, 默认:true */ visible?: boolean; /** * 搜索列标题field */ titleKey?: string; [key: string]: any; } & Partial>; /** * @description 数据模型:基础信息模块 */ export interface basicinfoProps extends SearchProps { /** * @description 是否可编辑, 默认不限制,new:新建,edit:修改 */ editable?: string[] | undefined; /** * @argument string 分组名称 */ group?: string; /** * @description 扩展显示字段, 待开发 */ extendsField?: string[]; /** * @description 是否隐藏字段, 默认:false */ ishidden?: boolean; disabledTextCallBack?: (data: any) => string; // 禁用按钮文字回调 /** * @argument boolean 编辑时form item验证规则 */ rules?: any; /** * @argument number 占用的行数,默认为1列 */ row?: number; /** * @description 是否禁止渲染详情页模式中的单元格 */ disabled?: boolean; } export type FieldNamesProps = { label: string; value: string; children?: string; }; export type RenderScope = { row: T; $index: number; column: VxeColumnProps; [key: string]: any; }; export type HeaderRenderScope = { $index: number; column: VxeColumnProps; [key: string]: any; }; export interface ColumnProps extends Partial, "children" | "renderCell" | "renderHeader">> { /** * @argument boolean 是否是标签展示 */ tag?: boolean; // /** // * @argument boolean 是否隐藏在表格当中 // */ // invisible?: boolean; /** * @argument object 列表页:搜索栏 */ search?: SearchProps | undefined; /** * @argument object 详情页:基础信息 */ basicinfo?: basicinfoProps | undefined; /** * @description search,筛选时,枚举类型(字典) */ enum?: EnumProps[] | ((params?: any) => Promise); /** * @description 过滤枚举 */ enumFilter?: (params: any, enumdata?: any, field?: string, orderStatus?: string) => EnumProps[]; isFilterEnum?: boolean; // 当前单元格值是否根据 enum 格式化(示例:enum 只作为搜索项数据) fieldNames?: FieldNamesProps; // enum 指定 label && value && children 的 key 值 headerRender?: (scope: HeaderRenderScope) => VNode; // 自定义表头内容渲染(tsx语法) /** * @description 自定义单元格内容渲染(tsx语法)- 用于表格展示/详情页浏览 */ render?: (scope: RenderScope, enumdata?: any, field?: string) => VNode | string; _children?: ColumnProps[]; // 多级表头 /** * @argument string[] 父级列表 */ parents?: string[]; /** * @argument boolean 是否隐藏父级表头 */ parentHidden?: boolean; /** * @argument number 排序 */ order?: VxeTablePropTypes.SortOrder; /** * @argument number 排序时间,比较先后顺序 */ sortTime?: number; /** * @argument number 列顺序 */ colorder?: number; /** * @argument 所属表格,通过i18n引导的标题title */ table?: string; // /** // * @argument string 字段类型, number, date, string,默认string,可根据field名称取值”date" // */ // fieldType?: string; /** * @argument string 辅助信息:数据来源,备注信息 */ dataSources?: string; /** * @argument TypeFormat 辅助信息:格式函数名 * | "yyyy-MM-dd" * | "yyyy-MM-dd HH:mm:ss" * | "yyyy-MM-dd HH:mm" * | "MM/dd/yyyy" * | "MM/dd" * | "dd/MM/yyyy" * | "yyyy/MM/dd" * | "cutNumber" 向下舍入,默认两位数 * | "amountNumber" 四舍五入金额,每隔3位逗号分隔,默认2位数 * | "fixedNumber" 四舍五入,默认两位数 * */ format?: TypeFormat; /** * @argument string 辅助信息:格式化,枚举类型(字典) */ formatEnum?: selectOption[] | ((params?: any) => Promise); /** * @argument boolean form item验证规则 */ rules?: any; /** * @augments boolean 是否限制显示 */ limited?: boolean; /** * @augments string 数据类型,用于赋值特殊字段的属性特征 */ datatype?: string; /** * @description 只对 tree-config 配置时有效,指定为树节点 */ treeNode?: boolean; } /** * @description vxeTable组件api */ export type aboutVxetableApiProps = { /** * @argument ColumnProps[] 列配置项 ==> 必传 */ columns?: ColumnProps[]; /** * @argument any 静态 table data 数据,若存在则不会使用 requestApi 返回的 data ==> 非必传 */ data?: any[]; /** * @argument string 请求表格数据的 api ==> 非必传 */ requestApi?: (params: any) => Promise; /** * @argument boolean 是否自动执行请求 api ==> 非必传(默认为true) */ requestAuto?: boolean; /** * @argument function 表格 api 请求错误监听 ==> 非必传 */ requestError?: (params: any) => void; /** * @argument function 返回数据的回调函数,可以对数据进行处理 ==> 非必传 */ dataCallback?: (data: any) => any; /** * @argument boolean 是否需要分页组件 ==> 非必传(默认为true) */ pagination?: boolean; pageSizes?: number[] | undefined; /** * @argument any 初始化请求参数 ==> 非必传(默认为{}) */ initParam?: any; /** * @argument string 布局窗口名称 */ dwname?: string; /** * @argument string[] 布局读取/保存时,赋值的属性名称; 支持单属名称、属性路径: ["search", "search.order"] */ layoutAttr?: string[]; /** * @argument Object 布局默认设置,保存时移除,默认的属性;包含search、basicinfo属性的默认值 */ layoutAttrDefine?: any; /** * @augments boolean 是否自动加载布局, 默认true;决定是否读取通用接口返回的布局 */ autoLoadLayout?: boolean; /** * @argument Array 打印前,事件检查 */ beforePrintCallback?: (data: any) => any; /** * @argument Array 打印前,获取打印数据 */ printDataCallback?: (data: any) => any; }; /** * @description 表格组件props */ export interface LjVxetableProps extends aboutVxetableApiProps { // /** // * @argument ColumnProps[] 列配置项 ==> 必传 // */ // columns: ColumnProps[]; // /** // * @argument any 静态 table data 数据,若存在则不会使用 requestApi 返回的 data ==> 非必传 // */ // data?: any[]; // /** // * @argument string 请求表格数据的 api ==> 非必传 // */ // requestApi?: (params: any) => Promise; // /** // * @argument boolean 是否自动执行请求 api ==> 非必传(默认为true) // */ // requestAuto?: boolean; // /** // * @argument function 表格 api 请求错误监听 ==> 非必传 // */ // requestError?: (params: any) => void; // /** // * @argument function 返回数据的回调函数,可以对数据进行处理 ==> 非必传 // */ // dataCallback?: (data: any) => any; // /** // * @argument boolean 是否需要分页组件 ==> 非必传(默认为true) // */ // pagination?: boolean; // pageSizes?: number[] | undefined; // /** // * @argument any 初始化请求参数 ==> 非必传(默认为{}) // */ // initParam?: any; /** * @argument string 表格标题,目前只在打印的时候用到 ==> 非必传 */ title?: string; // /** * @argument boolean 是否带有纵向边框 ==> 非必传(默认为true) default(默认), full(完整边框), outer(外边框), inner(内边框), none(无边框) */ border?: VxeTablePropTypes.Border; // /** // * @argument boolean 是否显示表格功能按钮 ==> 非必传(默认为true) // */ // toolButton?: boolean; /** * @argument string 行数据的 Key,用来优化 Table 的渲染,当表格数据多选时,所指定的 id ==> 非必传(默认为 id) */ rowKey?: string; /** * @argument number | Record 表格搜索项 每列占比配置 ==> 非必传 { xs: 1, sm: 2, md: 2, lg: 3, xl: 4 } */ searchCol?: number | Record; // /** // * @argument number | Record 表格设置项 每列占比配置 ==> 非必传 { xs: 1, sm: 2, md: 2, lg: 3, xl: 4 } // */ // settingCol?: number | Record; // /** // * @argument string 布局窗口名称 // */ // dwname?: string; // /** // * @argument string[] 布局读取/保存时,赋值的属性名称; 支持单属名称、属性路径: ["search", "search.order"] // */ // layoutAttr?: string[]; // /** // * @argument Object 布局默认设置,保存时移除,默认的属性;包含search、basicinfo属性的默认值 // */ // layoutAttrDefine?: any; // /** // * @argument string[] 搜索布局读取/保存时,赋值的属性名称 // */ // searchLayoutAttr?: string[]; // /** // * @argument Object 搜索默认设置,保存时移除,默认的属性 // */ // searchLayoutAttrDefine?: any; /** * 表尾 * @argument data */ footerMethod?: (data: any) => any | boolean; tableCls?: string; /** * @argument 继承 vxetable props: https://vxetable.cn/#/table/api */ tableProps?: any; /** * @argument 外置loading */ extraLoading?: boolean | undefined; /** * 给表头的单元格附加 className https://vxetable.cn/#/table/api?filterName=header-cell-class-name * @argument params column */ headerCellClassName?: (params: any) => any; /** * @argument Object 表格绑定的事件 */ tableEvents?: any; /** * @argument Array 表格按钮 * @enum "refresh": 刷新, "setting": 设置, "search": 搜索栏, "location": 定位, "guide": 指导 */ toolButton?: string[]; /** * @argument Array 表格按钮权限 * @attention 按钮权限,需要与按钮位置对应,若无/0,则默认显示 */ toolButtonPower?: number[]; // /** // * @argument Array 打印前,事件检查 // */ // beforePrintCallback?: (data: any) => any; // /** // * @argument Array 打印前,获取打印数据 // */ // printDataCallback?: (data: any) => any; /** * @argument boolean 折叠表格菜单按钮 */ collapseButtons?: boolean; /** * @description 表格搜索栏是否开启mini模式,即嵌套在slots[tableHeader]里面 */ miniSearchbar?: boolean; /** * @description 翻页后回调函数 */ pageChangeCallBack?: () => void; /** * @description 底部合计字段 */ footerSumAttrs?: string[]; /** * @description 搜索栏按钮需要缩小尺寸的屏幕尺寸,eg: ["xs", "sm"] */ searchBtnSizeExtent?: string[]; } export type LjVxeTableInstance = Omit, keyof ComponentPublicInstance | keyof LjVxetableProps>; /** * @description ElementPlus selecet option interface */ export interface selectOption { /** * @argument string 名称 */ label: string; /** * @argument string 值 */ value: string; /** * @argument boolean 是否禁用该选项 */ disabled?: boolean; } /** * @description 表格过滤器条件枚举 */ enum fModeEnum { /** * @description 包含 */ LIKE = "like", /** * @description 不包含 */ NOTLIKE = "notlike", /** * @description 等于 */ EQUAL = "equal", /** * @description 不等于 */ NE = "ne", /** * @description 大于 */ GREATER = "greater", /** * @description 大于等于 */ GE = "ge", /** * @description 小于 */ LESS = "less", /** * @description 小于等于 */ LE = "le" } export const hasValFunc = (target: any, val: any, fMode: string) => { let _t = Number(target); let _v = Number(val); let _target = isNaN(_t) ? target.toLowerCase() : target.toString(); let _val = isNaN(_t) ? val.toLowerCase() : val.toString(); switch (fMode) { case fModeEnum.LIKE: // 包含 // console.log("_target :>> ", _target); // console.log("_val :>> ", _val); // console.log("_target.indexOf(_val) :>> ", _target.indexOf(_val)); return _target.indexOf(_val) > -1; case fModeEnum.NOTLIKE: // 不包含 return _target.indexOf(_val) == -1; case fModeEnum.EQUAL: // 等于 return _target == _val; case fModeEnum.NE: // 不等于 return _target != _val; case fModeEnum.GREATER: // 大于 if (isNaN(_t) || isNaN(_v)) { return _target > _val; } else { return _t > _v; } case fModeEnum.GE: // 大于等于 if (isNaN(_t) || isNaN(_v)) { return _target >= _val; } else { return _t >= _v; } case fModeEnum.LESS: // 小于 if (isNaN(_t) || isNaN(_v)) { return _target < _val; } else { return _t < _v; } case fModeEnum.LE: // 小于等于 if (isNaN(_t) || isNaN(_v)) { return _target <= _val; } else { return _t <= _v; } } return _target.indexOf(_val) > -1; }; export const compareInputFunc = (target: any, val: any, fMode: string) => { let _val = val.replace(",", ","); if (_val.toString().indexOf(",") > -1) { let arr = _val.split(","); return arr.some((v: any) => hasValFunc(target, v, fMode)); } else { return hasValFunc(target, _val, fMode); } }; /** * @description 时间比较 * @param format 日期格式 * @param fMode 过滤器条件 * @param val 值 */ export const dataCompareFunc = (target: any, val: any, fMode: string, format: string) => { let _val = dayjs(dayjs(val).format(format)); let _target = dayjs(dayjs(target).format(format)); let diffType: any = "day"; if (format == "YYYY-MM-DD HH:mm") { diffType = "minute"; } switch (fMode) { case fModeEnum.EQUAL: // 等于 return _target.diff(_val, diffType) == 0; case fModeEnum.NE: // 不等于 return _target.diff(_val, diffType) != 0; case fModeEnum.GREATER: // 大于 return _target.diff(_val, diffType) > 0; case fModeEnum.GE: // 大于等于 return _target.diff(_val, diffType) >= 0; case fModeEnum.LESS: // 小于 return _target.diff(_val, diffType) < 0; case fModeEnum.LE: // 小于等于 return _target.diff(_val, diffType) <= 0; } }; // filter default const defaultFilter = [{ data: { vals: [], sVal: "", fMenu: "", f1Type: "", f1Val: "", fMode: "like", f2Type: "", f2Val: "" } }]; /** * @description 赋予特殊原始默认值 * 正则表达式匹配,特征"$"和”^“ * @param $ 以...结尾 * @param ^ 以...开头 */ const defineColumnStyle: any = { date: { fMode: fModeEnum.EQUAL }, datetime: { fMode: fModeEnum.EQUAL }, checkbox: { // width: 80 }, number: { fMode: fModeEnum.GE }, date$: { fMode: fModeEnum.EQUAL }, time$: { fMode: fModeEnum.EQUAL }, amt$: { fMode: fModeEnum.GE }, qty$: { fMode: fModeEnum.GE }, "^qty": { fMode: fModeEnum.GE }, price$: { fMode: fModeEnum.GE } }; export const getDefaultFilter = (item: any) => { let _define: any = {}; let _defaultFilter = cloneDeep(defaultFilter); if (item.hasOwnProperty("datatype")) { _define = cloneDeep(defineColumnStyle[item.datatype]); } else { for (const key in defineColumnStyle) { if (key.indexOf("$") > -1 || key.indexOf("^") > -1) { // 正则表达式 let reg = new RegExp(key); if (reg.test(item.field)) { _define = cloneDeep(defineColumnStyle[key]); break; } } } } _define && _define.hasOwnProperty("fMode") && (_defaultFilter[0].data.fMode = _define.fMode); return _defaultFilter; }; /** * @description 搜索方案 */ export interface searchProjectItem { /** * @description 名称 */ name: string; value: { [key: string]: any }; } /** * @description 保存布局,额外的属性 */ export interface dwnameSaveLayoutAttr { /** * @description vxetable属性 */ scrollY?: any; /** * @description 搜索栏相关属性 */ search?: any; /** * @description 详情页相关参数 */ basicinfo?: any; /** * @description 搜索方案 */ searchProject?: searchProjectItem[]; }