|
@@ -0,0 +1,519 @@
|
|
|
+<!--
|
|
|
+ * @Author: Gui
|
|
|
+ * @Date: 2023-03-01 19:20:44
|
|
|
+ * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
|
|
|
+ * @LastEditTime: 2025-02-14 15:48:40
|
|
|
+ * @Description: kxs files
|
|
|
+ * @filePath:
|
|
|
+-->
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref } from "vue";
|
|
|
+interface ColumnsType {
|
|
|
+ hide: Function;
|
|
|
+ slot: string;
|
|
|
+ cellRenderer: Function;
|
|
|
+ formatter: Function;
|
|
|
+ type: string;
|
|
|
+ index: number | Function;
|
|
|
+ label: string;
|
|
|
+ columnKey: string;
|
|
|
+ prop: string;
|
|
|
+ width: string | number;
|
|
|
+ minWidth: string | number;
|
|
|
+ fixed: string | boolean;
|
|
|
+ headerRenderer: Function;
|
|
|
+ sortable: boolean | string;
|
|
|
+ sortMethod: Function;
|
|
|
+ sortBy: Function | string | object;
|
|
|
+ sortOrders: object;
|
|
|
+ resizable: boolean;
|
|
|
+ formatterTable: Function;
|
|
|
+ showOverflowTooltip: boolean | object;
|
|
|
+ align: string;
|
|
|
+ headerAlign: string;
|
|
|
+ className: string;
|
|
|
+ labelClassName: string;
|
|
|
+ selectable: Function;
|
|
|
+ reserveSelection: boolean;
|
|
|
+ filters: Array<{ text: string; value: string }>;
|
|
|
+ filterPlacement: string;
|
|
|
+ filterClassName: string;
|
|
|
+ filterMultiple: boolean;
|
|
|
+ filterMethod: Function;
|
|
|
+ filteredValue: object;
|
|
|
+ tooltipFormatter: Function;
|
|
|
+}
|
|
|
+const props = defineProps({
|
|
|
+ data: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ height: {
|
|
|
+ type: String || Number,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ maxHeight: {
|
|
|
+ type: String || Number,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ stripe: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ border: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ size: {
|
|
|
+ type: String,
|
|
|
+ default: "default"
|
|
|
+ },
|
|
|
+ fit: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ showHeader: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ highlightCurrentRow: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ currentRowKey: {
|
|
|
+ type: String || Number,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ rowClassName: {
|
|
|
+ type: Function || String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ rowStyle: {
|
|
|
+ type: Function || Object,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ cellClassName: {
|
|
|
+ type: Function || String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ cellStyle: {
|
|
|
+ type: Function || Object,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ headerRowClassName: {
|
|
|
+ type: Function || String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ headerRowStyle: {
|
|
|
+ type: Function || Object,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ headerCellClassName: {
|
|
|
+ type: Function || String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ headerCellStyle: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {
|
|
|
+ background: "var(--el-table-row-hover-bg-color)",
|
|
|
+ color: "var(--el-text-color-primary)"
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ rowKey: {
|
|
|
+ type: String,
|
|
|
+ default: ""
|
|
|
+ },
|
|
|
+ emptyText: {
|
|
|
+ type: String,
|
|
|
+ default: ""
|
|
|
+ },
|
|
|
+ defaultExpandAll: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ expandRowKeys: {
|
|
|
+ type: Boolean,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ defaultSort: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return { prop: "date", order: "descending" };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ tooltipEffect: {
|
|
|
+ type: String,
|
|
|
+ default: "dark"
|
|
|
+ },
|
|
|
+ tooltipOptions: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {
|
|
|
+ enterable: true,
|
|
|
+ placement: "top",
|
|
|
+ showArrow: true,
|
|
|
+ hideAfter: 200,
|
|
|
+ popperOptions: { strategy: "fixed" }
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ appendFilterPanelTo: {
|
|
|
+ type: String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ showSummary: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ sumText: {
|
|
|
+ type: String,
|
|
|
+ default: "Sum"
|
|
|
+ },
|
|
|
+ summaryMethod: {
|
|
|
+ type: Function,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ spanMethod: {
|
|
|
+ type: Function,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ selectOnIndeterminate: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ indent: {
|
|
|
+ type: Number,
|
|
|
+ default: 16
|
|
|
+ },
|
|
|
+ lazy: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ load: {
|
|
|
+ type: Function,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ treeProps: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {
|
|
|
+ hasChildren: "hasChildren",
|
|
|
+ children: "children",
|
|
|
+ checkStrictly: false
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ tableLayout: {
|
|
|
+ type: String,
|
|
|
+ default: "fixed"
|
|
|
+ },
|
|
|
+ scrollbarAlwaysOn: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ showOverflowTooltip: {
|
|
|
+ type: Object,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ flexible: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ scrollbarTabindex: {
|
|
|
+ type: String || Number,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ allowDragLastColumn: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ tooltipFormatter: {
|
|
|
+ type: Function,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ alignWhole: {
|
|
|
+ type: String,
|
|
|
+ default: "center"
|
|
|
+ },
|
|
|
+ loading: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ columns: {
|
|
|
+ type: Array<ColumnsType>,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ checkList: {
|
|
|
+ type: Array,
|
|
|
+ default: () => []
|
|
|
+ },
|
|
|
+ disabled: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ pagination: {
|
|
|
+ type: Object,
|
|
|
+ default: () => {
|
|
|
+ return {
|
|
|
+ // 总数
|
|
|
+ total: 0,
|
|
|
+ // 条数
|
|
|
+ pageSize: 30,
|
|
|
+ // 页码
|
|
|
+ currentPage: 1,
|
|
|
+ background: true,
|
|
|
+ pageSizes: [10, 30, 50, 100]
|
|
|
+ };
|
|
|
+ }
|
|
|
+ },
|
|
|
+ paginationSmall: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ }
|
|
|
+});
|
|
|
+const emit = defineEmits([
|
|
|
+ "select",
|
|
|
+ "select-all",
|
|
|
+ "selection-change",
|
|
|
+ "cell-mouse-enter",
|
|
|
+ "cell-mouse-leave",
|
|
|
+ "cell-click",
|
|
|
+ "cell-dblclick",
|
|
|
+ "cell-contextmenu",
|
|
|
+ "row-click",
|
|
|
+ "row-contextmenu",
|
|
|
+ "row-dblclick",
|
|
|
+ "header-click",
|
|
|
+ "header-contextmenu",
|
|
|
+ "sort-change",
|
|
|
+ "filter-change",
|
|
|
+ "table-current-change",
|
|
|
+ "header-dragend",
|
|
|
+ "expand-change",
|
|
|
+ "scroll",
|
|
|
+ "size-change",
|
|
|
+ "current-change"
|
|
|
+]);
|
|
|
+const handleSizeChange = val => {
|
|
|
+ emit("size-change", val);
|
|
|
+};
|
|
|
+const handleCurrentChange = val => {
|
|
|
+ emit("current-change", val);
|
|
|
+};
|
|
|
+const handleSelectAll = val => {
|
|
|
+ emit("select-all", val);
|
|
|
+};
|
|
|
+const handleSelect = val => {
|
|
|
+ emit("select", val);
|
|
|
+};
|
|
|
+const handleSelectionChange = val => {
|
|
|
+ emit("selection-change", val);
|
|
|
+};
|
|
|
+const handleCellMouseEnter = val => {
|
|
|
+ emit("cell-mouse-enter", val);
|
|
|
+};
|
|
|
+const handleCellMouseLeave = val => {
|
|
|
+ emit("cell-mouse-leave", val);
|
|
|
+};
|
|
|
+const handleCellClick = val => {
|
|
|
+ emit("cell-click", val);
|
|
|
+};
|
|
|
+const handleCellDBLClick = val => {
|
|
|
+ emit("cell-dblclick", val);
|
|
|
+};
|
|
|
+const handleCellContextmenu = val => {
|
|
|
+ emit("cell-contextmenu", val);
|
|
|
+};
|
|
|
+const handleRowClick = val => {
|
|
|
+ emit("row-click", val);
|
|
|
+};
|
|
|
+const handleRowContextmenu = val => {
|
|
|
+ emit("row-contextmenu", val);
|
|
|
+};
|
|
|
+const handleRowDBLclick = val => {
|
|
|
+ emit("row-dblclick", val);
|
|
|
+};
|
|
|
+const handleHeaderClick = val => {
|
|
|
+ emit("header-click", val);
|
|
|
+};
|
|
|
+const handleHeaderContextmenu = val => {
|
|
|
+ emit("header-contextmenu", val);
|
|
|
+};
|
|
|
+const handleSortChange = val => {
|
|
|
+ emit("sort-change", val);
|
|
|
+};
|
|
|
+const handleFilterChange = val => {
|
|
|
+ emit("filter-change", val);
|
|
|
+};
|
|
|
+const handleTableCurrentChange = val => {
|
|
|
+ emit("table-current-change", val);
|
|
|
+};
|
|
|
+const handleHeaderDragend = val => {
|
|
|
+ emit("header-dragend", val);
|
|
|
+};
|
|
|
+const handleExpandChange = val => {
|
|
|
+ emit("expand-change", val);
|
|
|
+};
|
|
|
+const handleScroll = val => {
|
|
|
+ emit("scroll", val);
|
|
|
+};
|
|
|
+props.columns.forEach(element => {
|
|
|
+ element.formatterTable = element.cellRenderer
|
|
|
+ ? (row, column, index) => {
|
|
|
+ return element.cellRenderer({
|
|
|
+ row,
|
|
|
+ column,
|
|
|
+ index,
|
|
|
+ props: { size: props.size }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ : element.formatter
|
|
|
+ ? row => {
|
|
|
+ return element.formatter(row);
|
|
|
+ }
|
|
|
+ : null;
|
|
|
+});
|
|
|
+const tableRef = ref();
|
|
|
+
|
|
|
+defineExpose(
|
|
|
+ new Proxy(
|
|
|
+ {},
|
|
|
+ {
|
|
|
+ get(_target, prop) {
|
|
|
+ return tableRef.value?.[prop];
|
|
|
+ },
|
|
|
+ has(_target, prop) {
|
|
|
+ return prop in tableRef.value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+);
|
|
|
+</script>
|
|
|
+<script></script>
|
|
|
+<template>
|
|
|
+ <el-table
|
|
|
+ :data="data"
|
|
|
+ :height="height"
|
|
|
+ :max-height="maxHeight"
|
|
|
+ :stripe="stripe"
|
|
|
+ :border="border"
|
|
|
+ :size="size"
|
|
|
+ :fit="fit"
|
|
|
+ :show-header="showHeader"
|
|
|
+ :highlight-current-row="highlightCurrentRow"
|
|
|
+ :current-row-key="currentRowKey"
|
|
|
+ :row-class-name="rowClassName"
|
|
|
+ :row-style="rowStyle"
|
|
|
+ :cell-class-name="cellClassName"
|
|
|
+ :cell-style="cellStyle"
|
|
|
+ :header-row-class-name="headerRowClassName"
|
|
|
+ :header-row-style="headerRowStyle"
|
|
|
+ :header-cell-class-name="headerCellClassName"
|
|
|
+ :header-cell-style="headerCellStyle"
|
|
|
+ :row-key="rowKey"
|
|
|
+ :empty-text="emptyText"
|
|
|
+ :default-expand-all="defaultExpandAll"
|
|
|
+ :expand-row-keys="expandRowKeys"
|
|
|
+ :default-sort="defaultSort"
|
|
|
+ :tooltip-effect="tooltipEffect"
|
|
|
+ :tooltip-options="tooltipOptions"
|
|
|
+ :append-filter-panel-to="appendFilterPanelTo"
|
|
|
+ :show-summary="showSummary"
|
|
|
+ :sum-text="sumText"
|
|
|
+ :summary-method="summaryMethod"
|
|
|
+ :span-method="spanMethod"
|
|
|
+ :select-on-indeterminate="selectOnIndeterminate"
|
|
|
+ :indent="indent"
|
|
|
+ :lazy="lazy"
|
|
|
+ :load="load"
|
|
|
+ :tree-props="treeProps"
|
|
|
+ :table-layout="tableLayout"
|
|
|
+ :scrollbar-always-on="scrollbarAlwaysOn"
|
|
|
+ :show-overflow-tooltip="showOverflowTooltip"
|
|
|
+ :flexible="flexible"
|
|
|
+ :scrollbar-tabindex="scrollbarTabindex"
|
|
|
+ :allow-drag-last-column="allowDragLastColumn"
|
|
|
+ :tooltip-formatter="tooltipFormatter"
|
|
|
+ v-loading="loading"
|
|
|
+ style="width: 100%"
|
|
|
+ @select="handleSelect"
|
|
|
+ @select-all="handleSelectAll"
|
|
|
+ @selection-change="handleSelectionChange"
|
|
|
+ @cell-mouse-enter="handleCellMouseEnter"
|
|
|
+ @cell-mouse-leave="handleCellMouseLeave"
|
|
|
+ @cell-click="handleCellClick"
|
|
|
+ @cell-dblclick="handleCellDBLClick"
|
|
|
+ @cell-contextmenu="handleCellContextmenu"
|
|
|
+ @row-click="handleRowClick"
|
|
|
+ @row-contextmenu="handleRowContextmenu"
|
|
|
+ @row-dblclick="handleRowDBLclick"
|
|
|
+ @header-click="handleHeaderClick"
|
|
|
+ @header-contextmenu="handleHeaderContextmenu"
|
|
|
+ @sort-change="handleSortChange"
|
|
|
+ @filter-change="handleFilterChange"
|
|
|
+ @current-change="handleTableCurrentChange"
|
|
|
+ @header-dragend="handleHeaderDragend"
|
|
|
+ @expand-change="handleExpandChange"
|
|
|
+ @scroll="handleScroll"
|
|
|
+ ref="tableRef"
|
|
|
+ >
|
|
|
+ <template #append> <slot name="append" /> </template>
|
|
|
+ <template #empty> <slot name="empty" /> </template>
|
|
|
+
|
|
|
+ <template v-for="(item, index) in columns" :key="index">
|
|
|
+ <el-table-column
|
|
|
+ v-if="!item.hide || !item.hide({ checkList })"
|
|
|
+ :type="item.type"
|
|
|
+ :index="item.index"
|
|
|
+ :label="item.label"
|
|
|
+ :column-key="item.columnKey"
|
|
|
+ :prop="item.prop"
|
|
|
+ :width="item.width"
|
|
|
+ :min-width="item.minWidth"
|
|
|
+ :fixed="item.fixed"
|
|
|
+ :render-header="item.headerRenderer"
|
|
|
+ :sortable="item.sortable"
|
|
|
+ :sort-method="item.sortMethod"
|
|
|
+ :sort-by="item.sortBy"
|
|
|
+ :sort-orders="item.sortOrders"
|
|
|
+ :sort-resizable="item.resizable"
|
|
|
+ :formatter="item.formatterTable"
|
|
|
+ :show-overflow-tooltip="item.showOverflowTooltip"
|
|
|
+ :align="item.align || alignWhole"
|
|
|
+ :header-align="item.headerAlign"
|
|
|
+ :class-name="item.className"
|
|
|
+ :label-class-name="item.labelClassName"
|
|
|
+ :selectable="item.selectable"
|
|
|
+ :reserve-selection="item.reserveSelection"
|
|
|
+ :filters="item.filters"
|
|
|
+ :filter-placement="item.filterPlacement"
|
|
|
+ :filter-class-name="item.filterClassName"
|
|
|
+ :filter-multiple="item.filterMultiple"
|
|
|
+ :filter-method="item.filterMethod"
|
|
|
+ :filtered-value="item.filteredValue"
|
|
|
+ :tooltip-formatter="item.tooltipFormatter"
|
|
|
+ >
|
|
|
+ <template v-slot="{ row }">
|
|
|
+ <slot name="operation" :row="row" v-if="item.slot == 'operation'" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </template>
|
|
|
+ </el-table>
|
|
|
+ <div class="flex justify-end mb-4 mt-4">
|
|
|
+ <el-pagination
|
|
|
+ :current-page="pagination.currentPage"
|
|
|
+ :page-sizes="pagination.pageSizes"
|
|
|
+ :page-size="pagination.pageSize"
|
|
|
+ :size="size"
|
|
|
+ :disabled="disabled"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :total="pagination.total"
|
|
|
+ background
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+<style></style>
|