|
@@ -1,6 +1,7 @@
|
|
|
<!--
|
|
<!--
|
|
|
* @Descripttion: 数据表格组件
|
|
* @Descripttion: 数据表格组件
|
|
|
* @version: 1.10
|
|
* @version: 1.10
|
|
|
|
|
+ * @Date: 2025年12月04日15:35:06
|
|
|
-->
|
|
-->
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -29,7 +30,7 @@ import XEUtils from "xe-utils";
|
|
|
import store from "@/store";
|
|
import store from "@/store";
|
|
|
import config from "@/config/table";
|
|
import config from "@/config/table";
|
|
|
import pagerBatchDel from "./renderer/pager-batch-del";
|
|
import pagerBatchDel from "./renderer/pager-batch-del";
|
|
|
-import { watch, watchEffect } from "vue";
|
|
|
|
|
|
|
+import { computed, nextTick, watch, watchEffect } from "vue";
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
apiObj: { type: Object, default: () => ({}) },
|
|
apiObj: { type: Object, default: () => ({}) },
|
|
@@ -50,7 +51,34 @@ const props = defineProps({
|
|
|
options: { type: Object, default: () => ({}) }
|
|
options: { type: Object, default: () => ({}) }
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const foldedFormItems = computed(() => XEUtils.map(XEUtils.orderBy(XEUtils.filter(XEUtils.get(props.formConfig, "items", []), item => XEUtils.get(item, "visible", true)), "orderBy"), (item, index) => ({ ...item, folding: index > 2 })));
|
|
|
|
|
|
|
+const collapseStatus = ref(true);
|
|
|
|
|
+const foldedFormItems = ref(props.formConfig.items || []);
|
|
|
|
|
+const formItems = computed(() => {
|
|
|
|
|
+ const getActionSpan = () => {
|
|
|
|
|
+ const spanItems = collapseStatus.value ? XEUtils.filter(foldedFormItems.value, item => !item.folding) : foldedFormItems.value;
|
|
|
|
|
+ let totalSpan = 0;
|
|
|
|
|
+ XEUtils.arrayEach(spanItems, item => {
|
|
|
|
|
+ const itemSpan = (item.span || 6);
|
|
|
|
|
+ const remaining = 24 - (totalSpan % 24);
|
|
|
|
|
+ if (itemSpan > remaining) totalSpan += remaining;
|
|
|
|
|
+ totalSpan += itemSpan;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const remainder = 24 - (totalSpan % 24);
|
|
|
|
|
+ return remainder < 5 ? 24 : remainder;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return [
|
|
|
|
|
+ ...foldedFormItems.value, {
|
|
|
|
|
+ align: "right",
|
|
|
|
|
+ className: "query-action__item",
|
|
|
|
|
+ slots: { default: "queryAction" },
|
|
|
|
|
+ span: getActionSpan(),
|
|
|
|
|
+ visible: foldedFormItems.value.length > 0,
|
|
|
|
|
+ collapseNode: foldedFormItems.value.length > 3
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
const xGrid = ref();
|
|
const xGrid = ref();
|
|
|
const gridOptions = reactive({
|
|
const gridOptions = reactive({
|
|
@@ -67,31 +95,11 @@ const gridOptions = reactive({
|
|
|
layouts: props.layouts,
|
|
layouts: props.layouts,
|
|
|
formConfig: {
|
|
formConfig: {
|
|
|
enabled: true,
|
|
enabled: true,
|
|
|
- className: "vxe-table-query",
|
|
|
|
|
- titleAlign: "right",
|
|
|
|
|
- collapseStatus: true,
|
|
|
|
|
span: 6,
|
|
span: 6,
|
|
|
- items: [
|
|
|
|
|
- ...foldedFormItems.value, {
|
|
|
|
|
- align: "right",
|
|
|
|
|
- slots: { default: "queryAction" },
|
|
|
|
|
- visible: foldedFormItems.value.length > 0,
|
|
|
|
|
- collapseNode: foldedFormItems.value.length > 3,
|
|
|
|
|
- className: ({ item }) => {
|
|
|
|
|
- const spanItems = (!gridOptions.formConfig.collapseStatus && foldedFormItems.value) || XEUtils.filter(foldedFormItems.value, f_item => !f_item.folding);
|
|
|
|
|
- let spanItemsSum = 0;
|
|
|
|
|
- XEUtils.arrayEach(spanItems, s_item => {
|
|
|
|
|
- const spanCount = (s_item.span || 6);
|
|
|
|
|
- if (spanCount > 24 - (spanItemsSum % 24)) spanItemsSum += 24 - (spanItemsSum % 24);
|
|
|
|
|
- spanItemsSum += spanCount;
|
|
|
|
|
- })
|
|
|
|
|
- const remainder = 24 - (spanItemsSum % 24);
|
|
|
|
|
-
|
|
|
|
|
- item.span = remainder < 5 && 24 || remainder;
|
|
|
|
|
- return "query-action__item";
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ],
|
|
|
|
|
|
|
+ titleAlign: "right",
|
|
|
|
|
+ className: "vxe-table-query",
|
|
|
|
|
+ collapseStatus: collapseStatus,
|
|
|
|
|
+ items: formItems,
|
|
|
...XEUtils.omit(props.formConfig, "items")
|
|
...XEUtils.omit(props.formConfig, "items")
|
|
|
},
|
|
},
|
|
|
toolbarConfig: {
|
|
toolbarConfig: {
|
|
@@ -124,8 +132,8 @@ const gridOptions = reactive({
|
|
|
},
|
|
},
|
|
|
exportConfig: {
|
|
exportConfig: {
|
|
|
type: ["xlsx"],
|
|
type: ["xlsx"],
|
|
|
- modes: XEUtils.find(props.columns, item => XEUtils.get(item, "visible", true) && XEUtils.includes(config.exportExcludeFields, item.type)) && ["current", "selected", "all"] || ["current", "all"],
|
|
|
|
|
- columns: XEUtils.filter(props.columns, item => !(XEUtils.includes(config.exportExcludeFields, item.type)) && XEUtils.get(item, "visible", true)),
|
|
|
|
|
|
|
+ modes: XEUtils.find(props.columns, item => item.visible !== false && XEUtils.includes(config.exportExcludeFields, item.type)) && ["current", "selected", "all"] || ["current", "all"],
|
|
|
|
|
+ columns: XEUtils.filter(props.columns, item => !(XEUtils.includes(config.exportExcludeFields, item.type)) && item.visible !== false)
|
|
|
},
|
|
},
|
|
|
rowConfig: {
|
|
rowConfig: {
|
|
|
keyField: props.rowKey,
|
|
keyField: props.rowKey,
|
|
@@ -182,70 +190,72 @@ const gridOptions = reactive({
|
|
|
...props.options
|
|
...props.options
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+const formatScoped = context => ({ ...context, row: XEUtils.get(XEUtils.findTree(XEUtils.get(context, "$grid", XEUtils.get(context, "$table"))?.getData(), item => item.id == context.rowid), "item") || context.row });
|
|
|
|
|
+
|
|
|
|
|
+const resizeTable = XEUtils.debounce(() => {
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ if (store.state.global.ismobile) XEUtils.set(gridOptions, "maxHeight", 1048);
|
|
|
|
|
+ else XEUtils.set(gridOptions, "maxHeight", (props.maxHeight || xGrid.value?.$el.parentElement.offsetHeight) - 12);
|
|
|
|
|
+ });
|
|
|
|
|
+}, 300);
|
|
|
|
|
+
|
|
|
|
|
+const organizeFormItems = () => foldedFormItems.value = XEUtils.map(XEUtils.orderBy(XEUtils.filter(XEUtils.get(props.formConfig, "items", []), item => (item.visible !== false) && (!item.visibleMethod || item.visibleMethod(XEUtils.pick(props.formConfig, "data")))), "orderBy"), (item, index) => ({ ...item, folding: index > 2 }));
|
|
|
watchEffect(() => {
|
|
watchEffect(() => {
|
|
|
|
|
+ organizeFormItems();
|
|
|
XEUtils.objectEach(props.options, (value, key) => {
|
|
XEUtils.objectEach(props.options, (value, key) => {
|
|
|
if (XEUtils.has(gridOptions, key) && (XEUtils.isObject(value) || XEUtils.isArray(value))) XEUtils.merge(gridOptions[key], value);
|
|
if (XEUtils.has(gridOptions, key) && (XEUtils.isObject(value) || XEUtils.isArray(value))) XEUtils.merge(gridOptions[key], value);
|
|
|
else XEUtils.set(gridOptions, key, value);
|
|
else XEUtils.set(gridOptions, key, value);
|
|
|
});
|
|
});
|
|
|
-})
|
|
|
|
|
-
|
|
|
|
|
-watch(() => gridOptions.data, val => {
|
|
|
|
|
- if (props.columns.find(item => item.type == "checkbox" && XEUtils.get(item, "visible", true)) && props.checkedRows.length) {
|
|
|
|
|
- xGrid.value?.setCheckboxRow(props.checkedRows, true);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (props.columns.find(item => item.type == "radio" && XEUtils.get(item, "visible", true)) && props.checkedRows.length) {
|
|
|
|
|
- xGrid.value?.setRadioRow(XEUtils.first(props.checkedRows));
|
|
|
|
|
- }
|
|
|
|
|
-}, { deep: true });
|
|
|
|
|
|
|
|
|
|
-const formatScoped = context => ({ ...context, row: XEUtils.get(XEUtils.findTree(XEUtils.get(context, "$grid", XEUtils.get(context, "$table"))?.getData(), item => item.id == context.rowid), "item") || context.row });
|
|
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ if (props.checkedRows && props.checkedRows.length) {
|
|
|
|
|
+ props.columns.find(item => item.type == "checkbox" && item.visible !== false) && xGrid.value?.setCheckboxRow(props.checkedRows, true);
|
|
|
|
|
+ props.columns.find(item => item.type == "radio" && item.visible !== false) && xGrid.value?.setRadioRow(XEUtils.first(props.checkedRows));
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
-addEventListener("resize", () => resizeTable());
|
|
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
resizeTable();
|
|
resizeTable();
|
|
|
getData();
|
|
getData();
|
|
|
|
|
+ addEventListener("resize", resizeTable, { passive: true });
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const resizeTable = () => {
|
|
|
|
|
- nextTick(() => {
|
|
|
|
|
- if (store.state.global.ismobile) XEUtils.set(gridOptions, "maxHeight", 1048);
|
|
|
|
|
- else XEUtils.set(gridOptions, "maxHeight", (props.maxHeight || xGrid.value?.$el.parentElement.offsetHeight) - 12);
|
|
|
|
|
- });
|
|
|
|
|
-}
|
|
|
|
|
|
|
+onUnmounted(() => {
|
|
|
|
|
+ removeEventListener("resize", resizeTable);
|
|
|
|
|
+ resizeTable.cancel();
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
// 获取数据
|
|
// 获取数据
|
|
|
const getData = () => {
|
|
const getData = () => {
|
|
|
- nextTick(() => {
|
|
|
|
|
- if (!props.apiObj || XEUtils.isEmpty(props.apiObj)) {
|
|
|
|
|
- if (props.options.data && props.options.data.length > 0) {
|
|
|
|
|
- gridOptions.pagerConfig.total = props.options.data.length;
|
|
|
|
|
- return;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- gridOptions.data = [];
|
|
|
|
|
- gridOptions.pagerConfig.total = 0;
|
|
|
|
|
|
|
+ if (!props.apiObj || XEUtils.isEmpty(props.apiObj)) {
|
|
|
|
|
+ if (props.options.data && props.options.data.length > 0) {
|
|
|
|
|
+ gridOptions.pagerConfig.total = props.options.data.length;
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- gridOptions.loading = true;
|
|
|
|
|
- const reqData = config.queryData(gridOptions, props.paramsColums);
|
|
|
|
|
- props.apiObj[props.apiKey](reqData).then(res => {
|
|
|
|
|
- const response = config.parseData(res);
|
|
|
|
|
- gridOptions.data = response.data || [];
|
|
|
|
|
- gridOptions.pagerConfig.total = response.total || 0;
|
|
|
|
|
- gridOptions.loading = false;
|
|
|
|
|
- }).catch(error => {
|
|
|
|
|
- gridOptions.loading = false;
|
|
|
|
|
- gridOptions.data = [];
|
|
|
|
|
- gridOptions.pagerConfig.total = 0;
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ gridOptions.data = [];
|
|
|
|
|
+ gridOptions.pagerConfig.total = 0;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ gridOptions.loading = true;
|
|
|
|
|
+ const reqData = config.queryData(gridOptions, props.paramsColums);
|
|
|
|
|
+ props.apiObj[props.apiKey](reqData).then(res => {
|
|
|
|
|
+ const response = config.parseData(res);
|
|
|
|
|
+ gridOptions.data = response.data || [];
|
|
|
|
|
+ gridOptions.pagerConfig.total = response.total || 0;
|
|
|
|
|
+ gridOptions.loading = false;
|
|
|
|
|
+ }).catch(error => {
|
|
|
|
|
+ gridOptions.loading = false;
|
|
|
|
|
+ gridOptions.data = [];
|
|
|
|
|
+ gridOptions.pagerConfig.total = 0;
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const getAllData = () => {
|
|
const getAllData = () => {
|
|
|
return new Promise((resolve, reject) => {
|
|
return new Promise((resolve, reject) => {
|
|
|
- if (!props.apiObj) resolve([]);
|
|
|
|
|
|
|
+ if (!props.apiObj || XEUtils.isEmpty(props.apiObj)) resolve([]);
|
|
|
|
|
|
|
|
const reqData = config.queryExport(gridOptions, props.paramsColums);
|
|
const reqData = config.queryExport(gridOptions, props.paramsColums);
|
|
|
props.apiObj[props.apiKey](reqData).then(res => {
|
|
props.apiObj[props.apiKey](reqData).then(res => {
|
|
@@ -276,12 +286,12 @@ const resetData = () => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const getSelectRows = () => {
|
|
const getSelectRows = () => {
|
|
|
- if (props.columns.find(item => item.type == "checkbox" && XEUtils.get(item, "visible", true))) {
|
|
|
|
|
|
|
+ if (props.columns.find(item => item.type == "checkbox" && item.visible !== false)) {
|
|
|
const selectRecords = xGrid.value?.getCheckboxRecords();
|
|
const selectRecords = xGrid.value?.getCheckboxRecords();
|
|
|
const selectReserveRecords = xGrid.value?.getCheckboxReserveRecords();
|
|
const selectReserveRecords = xGrid.value?.getCheckboxReserveRecords();
|
|
|
return selectRecords.concat(selectReserveRecords);
|
|
return selectRecords.concat(selectReserveRecords);
|
|
|
}
|
|
}
|
|
|
- if (props.columns.find(item => item.type == "radio" && XEUtils.get(item, "visible", true))) {
|
|
|
|
|
|
|
+ if (props.columns.find(item => item.type == "radio" && item.visible !== false)) {
|
|
|
const currRow = xGrid.value?.getRadioRecord();
|
|
const currRow = xGrid.value?.getRadioRecord();
|
|
|
const currReserveRow = xGrid.value?.getRadioReserveRecord();
|
|
const currReserveRow = xGrid.value?.getRadioReserveRecord();
|
|
|
return [currRow || currReserveRow];
|
|
return [currRow || currReserveRow];
|
|
@@ -289,16 +299,10 @@ const getSelectRows = () => {
|
|
|
return [];
|
|
return [];
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-const formCollapseEvent = ({ collapse }) => gridOptions.formConfig.collapseStatus = collapse;
|
|
|
|
|
-
|
|
|
|
|
-const toggleTableLoading = value => gridOptions.loading = value;
|
|
|
|
|
-
|
|
|
|
|
-const toggleFormEnabled = () => gridOptions.formConfig.enabled = !gridOptions.formConfig.enabled;
|
|
|
|
|
|
|
+const formCollapseEvent = ({ collapse }) => collapseStatus.value = collapse;
|
|
|
|
|
|
|
|
const toggleTableExpand = () => xGrid.value.getTreeExpandRecords().length && xGrid.value.clearTreeExpand() || xGrid.value.setAllTreeExpand(true);
|
|
const toggleTableExpand = () => xGrid.value.getTreeExpandRecords().length && xGrid.value.clearTreeExpand() || xGrid.value.setAllTreeExpand(true);
|
|
|
|
|
|
|
|
-const toggleToolbarProps = obj => XEUtils.objectEach(obj, (value, key) => XEUtils.set(gridOptions.toolbarConfig, key, value));
|
|
|
|
|
-
|
|
|
|
|
const reloadColumn = columns => xGrid.value.reloadColumn(columns);
|
|
const reloadColumn = columns => xGrid.value.reloadColumn(columns);
|
|
|
|
|
|
|
|
const getTableData = () => xGrid.value.getTableData();
|
|
const getTableData = () => xGrid.value.getTableData();
|
|
@@ -320,10 +324,7 @@ const table_batch_del = ids => {
|
|
|
|
|
|
|
|
defineExpose({
|
|
defineExpose({
|
|
|
getSelectRows,
|
|
getSelectRows,
|
|
|
- toggleTableLoading,
|
|
|
|
|
- toggleFormEnabled,
|
|
|
|
|
toggleTableExpand,
|
|
toggleTableExpand,
|
|
|
- toggleToolbarProps,
|
|
|
|
|
reloadColumn,
|
|
reloadColumn,
|
|
|
getTableData,
|
|
getTableData,
|
|
|
reloadData,
|
|
reloadData,
|