Browse Source

表格优化提交

main
likunming 1 year ago
parent
commit
e2315d4bac
  1. 1
      io.sc.platform.core.frontend/src/platform/components/form/WForm.vue
  2. 2
      io.sc.platform.core.frontend/src/platform/components/form/elements/WCodeMirror.vue
  3. 100
      io.sc.platform.core.frontend/src/platform/components/form/elements/WIcon.vue
  4. 2
      io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue
  5. 99
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

1
io.sc.platform.core.frontend/src/platform/components/form/WForm.vue

@ -80,6 +80,7 @@ const fiedType = {
codeMirror: 'w-code-mirror',
position: 'w-position',
date: 'w-date',
icon: 'w-icon',
number: 'w-number',
select: 'w-select',
text: 'w-text',

2
io.sc.platform.core.frontend/src/platform/components/form/elements/WCodeMirror.vue

@ -21,7 +21,7 @@
<template #control>
<div ref="codemirrorRef" style="width: 100%" @focus.stop.prevent="() => {}" @click.stop.prevent="() => {}"></div>
</template>
<template v-if="!Tools.isEmpty(codeMirrorValue)" #append>
<template v-if="!Tools.isEmpty(codeMirrorValue) && attrs.button" #append>
<q-btn
round
dense

100
io.sc.platform.core.frontend/src/platform/components/form/elements/WIcon.vue

@ -1,7 +1,21 @@
<template>
<q-input v-model="valueRef" @update:model-value="valueChanged">
<div v-show="showIfComputed">
<q-input
ref="iconRef"
v-model="valueRef"
:hide-bottom-space="true"
:hide-hint="true"
:outlined="true"
:dense="true"
v-bind="attrs"
:rules="rulesComputed"
:readonly="readonlyIfComputed"
:disable="disableIfComputed"
@update:model-value="valueChanged"
>
<template #label> <span v-if="requiredIfComputed" style="color: red">*</span> {{ attrs.label }} </template>
<template #append>
<q-btn icon="bi-suit-heart" size="10px" padding="2px" flat square unelevated :title="$t('select')">
<q-btn :icon="Tools.isEmpty(valueRef) ? 'bi-suit-heart' : valueRef" size="10px" padding="2px" flat square unelevated :title="$t('select')">
<q-popup-proxy v-model:model-value="isShow" anchor="bottom right" self="top right" :offset="[0, 10]" @show="show">
<q-splitter v-model="leftWidthRef" style="width: 800px; height: 300px; position: relative">
<template #before>
@ -71,10 +85,12 @@
></q-btn>
</template>
</q-input>
</div>
</template>
<script setup lang="ts">
import { ref, toRaw, onMounted } from 'vue';
import { ref, toRaw, onMounted, computed, useAttrs, watch } from 'vue';
import { Tools } from '@/platform';
import { FormValidators } from '@/platform/components';
import bootstrap from './icons/bootstrap.json';
import materialIcons from './icons/material-icons.json';
import materialSymbolsOutlined from './icons/material-symbols-outlined.json';
@ -83,9 +99,42 @@ import fontawesomeBrands from './icons/fontawesome-v6-icons-brands.json';
import fontawesomeRegular from './icons/fontawesome-v6-icons-regular.json';
import fontawesomeSolid from './icons/fontawesome-v6-icons-solid.json';
const attrs = useAttrs();
const rules = attrs.rules;
const iconRef = ref();
const props = defineProps({
modelValue: { type: String, default: '' },
restore: { type: Boolean, default: false },
showIf: {
type: Function,
default: () => {
return true;
},
},
required: {
type: Boolean,
default: false,
},
requiredIf: {
type: Function,
default: undefined,
},
readonlyIf: {
type: Function,
default: () => {
return false;
},
},
disableIf: {
type: Function,
default: () => {
return false;
},
},
form: {
type: Object,
default: undefined,
},
});
const emit = defineEmits(['update:modelValue']);
@ -104,8 +153,53 @@ const selectedTab = ref('bootstrap');
const isShow = ref(false);
const searchRef = ref('');
const valueRef = ref(props.modelValue || 'bi-arrow-up-left-square');
watch(
() => props.modelValue,
(newVal, oldVal) => {
valueRef.value = newVal;
},
);
const restoreValue = toRaw(props.modelValue || '');
const rulesComputed = computed(() => {
let result = rules || <any>[];
if (showIfComputed.value && requiredIfComputed.value) {
result.push(FormValidators.required());
} else if (!showIfComputed.value) {
result = [];
}
if (iconRef?.value) {
iconRef.value.resetValidation();
}
return result;
});
const showIfComputed = computed(() => {
return props.showIf(props.form);
});
const requiredIfComputed = computed(() => {
if (props.requiredIf) {
return props.requiredIf(props.form) || false;
} else if (props.required) {
return true;
}
return false;
});
const readonlyIfComputed = computed(() => {
return props.readonlyIf(props.form);
});
const disableIfComputed = computed(() => {
return props.disableIf(props.form);
});
const computedStoreBackgroundColorValue = computed(() => {
const color: string = restoreValue;
if (color.toLowerCase() === 'white' || color.toLowerCase() === '#ffffff' || color.toLowerCase() === '#fff') {
return '#eee';
}
return undefined;
});
if (Tools.isEmpty(valueRef.value)) {
selectedTab.value = 'bootstrap';
} else if (valueRef.value.startsWith('bi')) {

2
io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue

@ -190,9 +190,9 @@ const selectedParent = (row, value) => {
parent[table.tickedField] = false;
}
}
}
selectedParent(parent, value);
}
}
};
//

99
io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue

@ -218,11 +218,11 @@
</template>
<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick, toRaw, useAttrs, getCurrentInstance, provide, watchEffect } from 'vue';
import { ref, reactive, computed, onMounted, nextTick, toRaw, useAttrs, getCurrentInstance, provide, watchEffect, watch } from 'vue';
import { axios, Environment, NotifyManager, TreeBuilder, VueTools, Tools } from '@/platform';
import { useQuasar, getCssVar, exportFile } from 'quasar';
import { IconEnum } from '@/platform/enums';
import { extractTableColumnsProps, arrayToMap, OperatorTypeEnum, isEmpty, PageStatusEnum } from '@/platform/components/utils';
import { arrayToMap, OperatorTypeEnum, isEmpty, PageStatusEnum } from '@/platform/components/utils';
import TreeGridRow from './TreeGridRow.vue';
import GridConfig from './GridConfig.vue';
@ -395,7 +395,61 @@ const dialogRef = ref();
const drawerRef = ref();
const dialogFormRef = ref();
const infoRef = ref();
const tableColumnsMap = arrayToMap('name', props.columns);
const tableColumns = ref(props.columns);
const tableColumnsMap = ref(arrayToMap('name', tableColumns.value));
const columnStyle = (item: any) => {
let style = '';
if (item.hasOwnProperty('style')) {
style = item.style;
}
if (item.hasOwnProperty('width')) {
if (typeof item.width === 'number') {
item.style = `min-width: ` + item.width + `px; width: ` + item.width + `px;max-width: ` + item.width + `px;` + style;
} else {
item.style = `min-width: ` + item.width + `; width: ` + item.width + `;max-width: ` + item.width + `;` + style;
}
delete item.width;
if (item.hasOwnProperty('classes')) {
item.classes = item.classes + ' truncate';
} else {
item.classes = 'truncate';
}
}
};
const columnChildrenHandler = (item: any, gridColumns: any) => {
if (item.columns && item.columns.length > 0) {
item.columns.forEach((column) => {
columnChildrenHandler(column, gridColumns);
});
} else {
columnStyle(item);
gridColumns.push({
...{ align: 'left', label: item.name, field: item.name, sortable: true, hidden: false },
...item,
});
}
};
const extractTableColumnsProps = () => {
const gridColumns = <any>[];
if (tableColumns.value && tableColumns.value.length > 0) {
gridColumns.push({ name: '_sortNo_', align: 'center', label: '序号', field: '_sortNo_', hidden: props.sortNo ? false : true });
tableColumns.value.forEach((item: any) => {
columnChildrenHandler(item, gridColumns);
});
return gridColumns;
}
return [];
};
const extractTableColumns = ref(extractTableColumnsProps());
watch(
() => props.columns,
(newVal, oldVal) => {
tableColumns.value = newVal;
tableColumnsMap.value = arrayToMap('name', tableColumns.value);
extractTableColumns.value = extractTableColumnsProps();
},
);
const queryFormFieldsMap = arrayToMap('name', props.queryFormFields);
const rowKey_ = '_rowKey_'; // UUID
const url = {
@ -406,11 +460,10 @@ const url = {
removeDataUrl: props.removeDataUrl,
};
const extractTableColumns = extractTableColumnsProps(props);
// props
const titleScopeHandler = (column: any, scope: any) => {
if (extractTableColumns && extractTableColumns.length > 0) {
const i = extractTableColumns.findIndex((item) => item.name === column.name);
if (extractTableColumns.value && extractTableColumns.value.length > 0) {
const i = extractTableColumns.value.findIndex((item) => item.name === column.name);
if (i > -1) {
return scope;
}
@ -425,7 +478,7 @@ const table = reactive({
allTicked: <null | boolean>false,
gridConfig: false,
stickyNum: props.stickyNum,
columns: extractTableColumns,
columns: extractTableColumns.value,
treeExpand: props.treeDefaultExpandAll,
checkboxSelection: props.checkboxSelection,
sortNo: props.sortNo,
@ -660,10 +713,10 @@ const buttonObj = {
icon: 'file_download',
label: '导出',
click: (selected, context) => {
const content = [props.columns.map((col) => wrapCsvValue(col.label))]
const content = [tableColumns.value.map((col) => wrapCsvValue(col.label))]
.concat(
table.rows.map((row) =>
props.columns
tableColumns.value
.map((col) => wrapCsvValue(typeof col.field === 'function' ? col.field(row) : row[col.field === void 0 ? col.name : col.field], col.format, row))
.join(','),
),
@ -1004,7 +1057,7 @@ function findParents(arrData: any, name: any) {
}
const handlerMoreRowColumnTitle = () => {
props.columns.forEach((tableColumn: any) => {
tableColumns.value.forEach((tableColumn: any) => {
columnToMap(tableColumn);
});
let maxColumnChildrenLevel = 0;
@ -1024,7 +1077,7 @@ const handlerMoreRowColumnTitle = () => {
tmpColspan = 0;
// parent
const parent = findParents(props.columns, key);
const parent = findParents(tableColumns.value, key);
moreColumnTitleMap.get(key)!.parents = parent;
// parentLevel
@ -1076,7 +1129,7 @@ const tableHeightComputed = computed(() => {
//
const screenHeight = $q.screen.height;
// XX
const footerHeight = gc.theme.footer.enable ? gc.theme.footer.height : 0;
const footerHeight = gc.theme.footer.show ? gc.theme.footer.height : 0;
//
const mainPaddingBottom = gc.theme.main.paddingBottom || 0;
//
@ -1107,7 +1160,7 @@ const noDataBottomHeightComputed = computed(() => {
//
const screenHeight = $q.screen.height;
// XX
const footerHeight = gc.theme.footer.enable ? gc.theme.footer.height : 0;
const footerHeight = gc.theme.footer.show ? gc.theme.footer.height : 0;
// 4px
const otherHeight = table.spaceHeight || 4;
//
@ -1404,10 +1457,10 @@ const view = () => {
viewInfo.infoArray.push({ label: item.label, value: value, originalValue: getSelectedRowsComputed.value[0][item.name] });
} else {
let value = null;
if (tableColumnsMap.get(item.name) && tableColumnsMap.get(item.name).format) {
if (tableColumnsMap.value.get(item.name) && tableColumnsMap.value.get(item.name).format) {
value = getSelectedRowsComputed.value[0][item.name];
try {
value = tableColumnsMap.get(item.name).format(getSelectedRowsComputed.value[0][item.name], getSelectedRowsComputed.value[0]);
value = tableColumnsMap.value.get(item.name).format(getSelectedRowsComputed.value[0][item.name], getSelectedRowsComputed.value[0]);
} catch (error) {
console.error('format error!');
}
@ -1418,7 +1471,7 @@ const view = () => {
}
}
} else {
for (let item of tableColumnsMap) {
for (let item of tableColumnsMap.value) {
if (item[1].format) {
let value = getSelectedRowsComputed.value[0][item[0]];
try {
@ -1455,8 +1508,14 @@ const wrapCsvValue = (val, formatFn, row) => {
//
const setLocalData = (rows: any) => {
if (props.tree && props.treeRelationship === 'parent') {
const treeRows = TreeBuilder.build(rows, props.foreignKey, props.primaryKey);
table.rows = treeRows;
} else {
table.rows = rows;
}
addRowKey(table.rows);
state.pagination.rowsNumber = table.rows.length;
stickyHeaderColumn();
};
//
@ -1478,6 +1537,7 @@ const removeRows = (rows) => {
1,
);
});
state.pagination.rowsNumber = table.rows.length;
stickyHeaderColumn();
};
//
@ -1488,6 +1548,7 @@ const addRow = (row, index) => {
table.rows.splice(index, 0, row);
}
addRowKey(table.rows);
state.pagination.rowsNumber = table.rows.length;
stickyHeaderColumn();
};
@ -1705,7 +1766,7 @@ const handlerStickyChildrenColumn = (item, columns) => {
}
};
const getStickyColumn = () => {
const columns = props.columns.filter((item, index) => {
const columns = tableColumns.value.filter((item, index) => {
return index < table.stickyNum;
});
const arr = [];
@ -1880,7 +1941,7 @@ const tableClassComputed = computed(() => {
if (table.stickyNum && table.stickyNum > 0) {
if (columnTitleState.columnTitleRowNum > 1) {
//
const stickyColumn = props.columns.filter((item, index) => {
const stickyColumn = tableColumns.value.filter((item, index) => {
return index < table.stickyNum;
});
let tdNum = excludeColumnNum.value;
@ -2035,7 +2096,7 @@ const handlerQueryFormShowField = () => {
};
onMounted(() => {
if (extractTableColumns && extractTableColumns.length > props.columns.length) {
if (extractTableColumns.value && extractTableColumns.value > tableColumns.value.length) {
handlerMoreRowColumnTitle();
}
handlerQueryFormShowField();

Loading…
Cancel
Save