Browse Source

表格优化提交

main
likunming 1 year ago
parent
commit
1d2665c940
  1. 2
      io.sc.platform.core.frontend/src/platform/components/form/WForm.vue
  2. 296
      io.sc.platform.core.frontend/src/platform/components/grid/GridConfig.vue
  3. 18
      io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue
  4. 450
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  5. 14
      io.sc.platform.core.frontend/src/platform/components/toolbar/ChildrenBtn.vue
  6. 13
      io.sc.platform.core.frontend/src/platform/components/toolbar/WToolbar.vue
  7. 6
      io.sc.platform.core.frontend/src/platform/components/utils/componentComm.ts
  8. 112
      io.sc.platform.core.frontend/src/views/likm/Grid.vue
  9. 41
      io.sc.platform.core.frontend/src/views/likm/TreeGrid.vue

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

@ -72,7 +72,7 @@ const fiedType = {
const defaultValueHandler = (field) => {
if (field.hasOwnProperty('defaultValue') && field.defaultValue !== null && field.defaultValue !== undefined) {
return field.defaultValue;
} else if (field.type === 'w-checkbox') {
} else if (field.type === 'checkbox' || field.type === 'w-checkbox') {
return false;
}
return null;

296
io.sc.platform.core.frontend/src/platform/components/grid/GridConfig.vue

@ -0,0 +1,296 @@
<template>
<q-list padding style="min-width: 250px">
<q-item :clickable="false" dense>
<q-item-section>
<q-item-label>全屏</q-item-label>
</q-item-section>
<q-item-section side>
<q-btn-group outline flat dense unelevated spread>
<q-btn
:color="!scope.inFullscreen ? 'primary' : ''"
:outline="scope.inFullscreen ? true : false"
dense
label="正常"
unelevated
@click="
() => {
if (scope.inFullscreen) {
scope.toggleFullscreen();
table.gridConfig = false;
}
}
"
/>
<q-btn
:color="scope.inFullscreen ? 'primary' : ''"
:outline="!scope.inFullscreen ? true : false"
dense
label="全屏"
unelevated
@click="
() => {
if (!scope.inFullscreen) {
scope.toggleFullscreen();
table.gridConfig = false;
}
}
"
/>
</q-btn-group>
</q-item-section>
</q-item>
<q-separator spaced />
<q-item :clickable="false" dense>
<q-item-section>
<q-item-label>复选框</q-item-label>
</q-item-section>
<q-item-section side>
<q-btn-group outline flat dense unelevated spread>
<q-btn
:color="table.checkboxSelection ? 'primary' : ''"
:outline="table.checkboxSelection ? false : true"
dense
label="显示"
unelevated
@click="
() => {
table.checkboxSelection = true;
grid.stickyHeaderColumn(100);
}
"
/>
<q-btn
:color="table.checkboxSelection ? '' : 'primary'"
:outline="table.checkboxSelection ? true : false"
dense
label="隐藏"
unelevated
@click="
() => {
table.checkboxSelection = false;
grid.stickyHeaderColumn(100);
}
"
/>
</q-btn-group>
</q-item-section>
</q-item>
<template v-if="!gridProps.tree">
<q-separator spaced />
<q-item :clickable="false" dense>
<q-item-section>
<q-item-label>序号</q-item-label>
</q-item-section>
<q-item-section side>
<q-btn-group outline flat dense unelevated spread>
<q-btn
:color="table.sortNo ? 'primary' : ''"
:outline="table.sortNo ? false : true"
dense
label="显示"
unelevated
@click="
() => {
table.columns[0].hidden = false;
table.sortNo = true;
grid.stickyHeaderColumn(100);
}
"
/>
<q-btn
:color="table.sortNo ? '' : 'primary'"
:outline="table.sortNo ? true : false"
dense
label="隐藏"
unelevated
@click="
() => {
table.columns[0].hidden = true;
table.sortNo = false;
grid.stickyHeaderColumn(100);
}
"
/>
</q-btn-group>
</q-item-section>
</q-item>
</template>
<q-separator spaced />
<q-expansion-item label="紧凑模式">
<q-card>
<q-card-section>
<q-item v-ripple tag="label" dense :disable="denseDisableComputed">
<q-item-section side>
<q-checkbox v-model="table.dense" dense :disable="denseDisableComputed" @update:model-value="denseChange()" />
</q-item-section>
<q-item-section>
<q-item-label>紧凑</q-item-label>
</q-item-section>
</q-item>
<q-item v-ripple tag="label" dense :disable="denseOtherDisableComputed">
<q-item-section side>
<q-checkbox v-model="table.denseToolbar" :disable="denseOtherDisableComputed" dense @update:model-value="denseChange" />
</q-item-section>
<q-item-section>
<q-item-label>按钮栏紧凑</q-item-label>
</q-item-section>
</q-item>
<q-item v-ripple tag="label" dense :disable="denseOtherDisableComputed">
<q-item-section side>
<q-checkbox v-model="table.denseHeader" :disable="denseOtherDisableComputed" dense @update:model-value="denseChange" />
</q-item-section>
<q-item-section>
<q-item-label>列头紧凑</q-item-label>
</q-item-section>
</q-item>
<q-item v-ripple tag="label" dense :disable="denseOtherDisableComputed">
<q-item-section side>
<q-checkbox v-model="table.denseBody" :disable="denseOtherDisableComputed" dense @update:model-value="denseChange" />
</q-item-section>
<q-item-section>
<q-item-label>内容紧凑</q-item-label>
</q-item-section>
</q-item>
<q-item v-ripple tag="label" dense :disable="denseOtherDisableComputed">
<q-item-section side>
<q-checkbox v-model="table.denseBottom" :disable="denseOtherDisableComputed" dense @update:model-value="denseChange" />
</q-item-section>
<q-item-section>
<q-item-label>分页栏紧凑</q-item-label>
</q-item-section>
</q-item>
</q-card-section>
</q-card>
</q-expansion-item>
<q-separator spaced />
<q-item :clickable="false" dense>
<q-item-section>
<q-item-label class="nowrap text-nowrap">固定列</q-item-label>
</q-item-section>
<q-item-section side>
<q-select
v-model="table.stickyNum"
emit-value
map-options
:hide-bottom-space="true"
:hide-hint="true"
:outlined="true"
:dense="true"
:options="stickyOptions"
@update:model-value="
() => {
grid.stickyHeaderColumn(500);
}
"
>
</q-select>
</q-item-section>
</q-item>
<q-separator spaced />
<q-item-label header>显示列</q-item-label>
<template v-for="col in table.columns" :key="col.name">
<q-item v-if="showColumn(col.name)" v-ripple tag="label" dense>
<q-item-section side>
<q-checkbox
v-model="col.hidden"
:false-value="true"
:true-value="false"
dense
@update:model-value="
() => {
grid.stickyHeaderColumn(100);
}
"
/>
</q-item-section>
<q-item-section>
<q-item-label>{{ col.label || col.name }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-list>
</template>
<script setup lang="ts">
import { ref, reactive, computed, watch, inject } from 'vue';
const props = defineProps({
scope: {
type: Object,
default: () => {
return {};
},
},
gridProps: {
type: Object,
default: () => {
return {};
},
},
moreColumnTitleArray: {
//
type: Array,
default: () => {
return [];
},
},
grid: {
type: Object,
default: () => {
return {};
},
},
});
const table = inject('table');
const stickyOptions = [
{ label: '不固定', value: 0 },
{ label: '固定1列', value: 1 },
{ label: '固定2列', value: 2 },
{ label: '固定3列', value: 3 },
{ label: '固定4列', value: 4 },
{ label: '固定5列', value: 5 },
{ label: '固定6列', value: 6 },
{ label: '固定7列', value: 7 },
{ label: '固定8列', value: 8 },
{ label: '固定9列', value: 9 },
{ label: '固定10列', value: 10 },
];
const sticky = ref(0);
const showColumn = (name) => {
if (props.moreColumnTitleArray.length > 0) {
if (
props.moreColumnTitleArray[0].findIndex((item) => {
return item.name === name;
}) > -1
) {
return true;
} else {
return false;
}
} else {
return true;
}
};
const denseChange = () => {
props.grid.stickyHeaderColumn(0);
};
const denseDisableComputed = computed(() => {
if (table.denseToolbar || table.denseHeader || table.denseBody || table.denseBottom) {
return true;
}
return false;
});
const denseOtherDisableComputed = computed(() => {
if (table.dense) {
return true;
}
return false;
});
</script>

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

@ -16,13 +16,7 @@
<!--展开按钮占位符-->
<span v-else style="width: 27px"></span>
<!--选择框-->
<q-checkbox
v-if="gridProps.checkboxSelection"
v-model="state.currRow.selected"
flat
dense
@update:model-value="selectedFun(state.currRow.selected, row)"
/>
<q-checkbox v-if="table.checkboxSelection" v-model="state.currRow.selected" flat dense @update:model-value="selectedFun(state.currRow.selected, row)" />
<!--图标-->
<q-icon v-if="typeof iconComputed === 'string'" :name="iconComputed" size="20px" class="px-1"></q-icon>
<q-icon v-else-if="typeof iconComputed === 'object'" size="20px" v-bind="iconComputed" class="px-1"></q-icon>
@ -38,8 +32,12 @@
</div>
</q-td>
<template v-for="(col, index) in cols" :key="col.name">
<q-td v-if="index > 0" :title="col.classes?.indexOf('truncate') > -1 ? col.value : ''" @click="click($event, row, row.rowIndex)">
<div class="flex flex-nowrap items-center">
<q-td
v-if="index > 0"
:title="col.classes?.indexOf('truncate') > -1 && col.value && typeof col.value !== 'object' ? col.value : ''"
@click="click($event, row, row.rowIndex)"
>
<div :class="col.__thClass">
<template v-if="col.value && typeof col.value === 'object' && col.value.componentType">
<component :is="col.value.componentType" v-bind="col.value.attrs"></component>
</template>
@ -59,7 +57,6 @@
:level="props.level + 1"
:grid-props="gridProps"
:row-key="props.rowKey"
:selection="props.selection"
></TreeGridRow>
</template>
</template>
@ -92,7 +89,6 @@ const props = defineProps({
},
},
rowKey: { type: String, default: '_rowKey_' },
selection: { type: String, default: 'single' },
});
const table = inject('table');

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

@ -2,22 +2,23 @@
<div>
<q-table
ref="tableRef"
v-model:pagination="table.pagination"
v-model:pagination="state.pagination"
v-model:selected="table.selected"
flat
binary-state-sort
:no-data-label="table.noDataLabel"
:loading-label="table.loadingLabel"
:no-data-label="state.noDataLabel"
:loading-label="state.loadingLabel"
v-bind="attrs"
:selection="selectionComputed"
separator="cell"
:rows="table.rows"
:columns="extractTableColumns"
:rows-per-page-options="pageable && !tree && table.refHeightWidth.middleWidth > 600 ? table.pagination.rowsPerPageOptions : []"
:loading="table.loading"
:rows-per-page-options="pageable && !tree && state.refHeightWidth.middleWidth > 600 ? state.pagination.rowsPerPageOptions : []"
:loading="state.loading"
:class="tableClassComputed"
:table-style="tableHeightComputed"
:row-key="rowKey_"
:visible-columns="visibleColumnsComputed"
@request="onRequest"
@fullscreen="tableFullscreenFun"
>
@ -29,6 +30,7 @@
<div class="flex-none">{{ title }}</div>
<div class="flex-1">
<w-toolbar
:dense="denseToolbarComputed"
v-bind="toolbarConfigure"
:buttons="buttons_"
:grid-props="{
@ -37,11 +39,11 @@
}"
></w-toolbar>
</div>
<div v-if="fullScreenButton" class="flex-none pl-1">
<q-btn :icon="scope.inFullscreen ? IconEnum.退出全屏 : IconEnum.全屏" unelevated outline @click="scope.toggleFullscreen">
<q-tooltip transition-show="rotate" transition-hide="rotate">
{{ scope.inFullscreen ? '退出全屏' : '全屏' }}
</q-tooltip>
<div v-if="configButton" class="flex-none pl-1">
<q-btn round dense :size="denseToolbarComputed ? '13px' : '14px'" :icon="IconEnum.设置" unelevated outline>
<q-popup-proxy v-model="table.gridConfig">
<GridConfig :scope="scope" :grid-props="props" :more-column-title-array="columnTitleState.columnTitleArr" :grid="instance"></GridConfig>
</q-popup-proxy>
</q-btn>
</div>
</div>
@ -52,13 +54,15 @@
<template v-if="columnTitleState.columnTitleRowNum > 1">
<q-tr v-for="(r, rIndex) in columnTitleState.columnTitleArr" :key="rIndex">
<q-th
v-if="rIndex === 0 && selectionComputed === 'multiple' && props.checkboxSelection && !props.tree"
v-if="rIndex === 0 && selectionComputed === 'multiple' && table.checkboxSelection && !props.tree"
:rowspan="columnTitleState.columnTitleRowNum"
:style="moreColumnTitleTableSelectionStyle"
>
<q-checkbox v-model="scope.selected" flat :dense="denseHeader || attrs.dense ? true : false" />
<q-checkbox v-model="scope.selected" flat :dense="denseHeaderComputed" />
</q-th>
<q-th v-if="rIndex === 0 && table.sortNo && !props.tree" :rowspan="columnTitleState.columnTitleRowNum" :style="moreColumnTitleTableSortNoStyle">
序号
</q-th>
<q-th v-if="rIndex === 0 && props.sortNo" :rowspan="columnTitleState.columnTitleRowNum" :style="moreColumnTitleTableSortNoStyle"> 序号 </q-th>
<q-th
v-for="c in r"
:key="c.name"
@ -67,6 +71,7 @@
:style="thStyleHandler(c, scope)"
:class="c.classes"
:props="titleScopeHandler(c, scope)"
style="font-weight: bold"
>
{{ c.label }}
</q-th>
@ -75,33 +80,33 @@
<template v-else>
<q-tr :props="scope">
<q-th
v-if="selectionComputed === 'multiple' && props.checkboxSelection && !props.tree"
v-if="selectionComputed === 'multiple' && table.checkboxSelection && !props.tree"
:style="props.tree ? '' : 'padding: 0; width: 50px'"
auto-width
>
<q-checkbox v-model="scope.selected" flat :dense="denseHeader || attrs.dense ? true : false"
<q-checkbox v-model="scope.selected" flat :dense="denseHeaderComputed"
/></q-th>
<q-th v-else-if="props.checkboxSelection && !props.tree"></q-th>
<q-th v-for="col in scope.cols" :key="col.name" :props="scope" :style="col.style" :class="col.classes">
<q-th v-else-if="table.checkboxSelection && !props.tree"></q-th>
<template v-for="col in scope.cols" :key="col.name">
<q-th
:props="scope"
:style="col.style + (col.name === '_sortNo_' ? 'padding: 0; width: 50px;' : '')"
:class="col.classes"
style="font-weight: bold"
>
{{ col.label }}
</q-th>
</template>
</q-tr>
</template>
</template>
<template #body="scope">
<template v-if="tree">
<TreeGridRow
:columns-map="tableColumnsMap"
:row="scope.row"
:cols="scope.cols"
:grid-props="props"
:row-key="rowKey_"
:selection="selectionComputed"
></TreeGridRow>
<TreeGridRow :columns-map="tableColumnsMap" :row="scope.row" :cols="scope.cols" :grid-props="props" :row-key="rowKey_"></TreeGridRow>
</template>
<q-tr v-else :props="scope" @click="rowClick($event, scope.row, scope.rowIndex)" @dblclick="rowDbClick($el, scope.row, scope.rowIndex)">
<q-td v-if="props.checkboxSelection" class="text-center" style="padding: 0; width: 50px">
<q-checkbox v-model="scope.selected" flat :dense="denseBody || attrs.dense ? true : false" />
<q-td v-if="table.checkboxSelection" class="text-center" style="padding: 0; width: 50px">
<q-checkbox v-model="scope.selected" flat :dense="denseBodyComputed" />
</q-td>
<template v-if="draggable">
<q-td
@ -128,7 +133,12 @@
</q-td>
</template>
<template v-else>
<q-td v-for="col in scope.cols" :key="col.name" :props="scope" :title="col.classes?.indexOf('truncate') > -1 ? col.value : ''">
<q-td
v-for="col in scope.cols"
:key="col.name"
:props="scope"
:title="col.classes?.indexOf('truncate') > -1 && col.value && typeof col.value !== 'object' ? col.value : ''"
>
<template v-if="col.name === '_sortNo_'">
{{ scope.rowIndex + 1 }}
</template>
@ -143,41 +153,43 @@
</q-tr>
</template>
<template #loading>
<q-inner-loading :showing="table.loading" style="z-index: 999">
<q-inner-loading :showing="state.loading" style="z-index: 999">
<q-spinner-gears size="50px" color="primary" />
</q-inner-loading>
</template>
<template #pagination="scope">
<template v-if="pageable && !tree">
<template v-if="table.refHeightWidth.middleWidth > 600">
<template v-if="state.refHeightWidth.middleWidth > 600">
<q-pagination
v-model="table.pagination.page"
:boundary-links="table.pagination.config.boundaryLinks"
:boundary-numbers="table.pagination.config.boundaryNumbers"
:direction-links="table.pagination.config.directionLinks"
:ellipses="table.pagination.config.ellipses"
:max-pages="table.pagination.config.maxPages"
v-model="state.pagination.page"
:boundary-links="state.pagination.config.boundaryLinks"
:boundary-numbers="state.pagination.config.boundaryNumbers"
:direction-links="state.pagination.config.directionLinks"
:ellipses="state.pagination.config.ellipses"
:max-pages="state.pagination.config.maxPages"
:min="1"
:max="scope.pagesNumber"
:size="denseBottomComputed ? '10px' : ''"
@update:model-value="pageChange"
/>
</template>
<template v-else>
<q-pagination
v-model="table.pagination.page"
:boundary-links="table.pagination.config.boundaryLinks"
:boundary-numbers="table.pagination.config.boundaryNumbers"
:direction-links="table.pagination.config.directionLinks"
:ellipses="table.pagination.config.ellipses"
v-model="state.pagination.page"
:boundary-links="state.pagination.config.boundaryLinks"
:boundary-numbers="state.pagination.config.boundaryNumbers"
:direction-links="state.pagination.config.directionLinks"
:ellipses="state.pagination.config.ellipses"
:max-pages="3"
:min="1"
:max="scope.pagesNumber"
:size="denseBottomComputed ? '10px' : ''"
@update:model-value="pageChange"
/>
</template>
<span> {{ table.pagination.rowsNumber }} 条记录</span>
<span> {{ state.pagination.rowsNumber }} 条记录</span>
</template>
<template v-else> 当前未启用分页 {{ table.pagination.rowsNumber }} 条记录 </template>
<template v-else> {{ state.pagination.rowsNumber }} 条记录 </template>
</template>
<template v-if="!attrs.hideBottom" #no-data="{ message }">
<div class="full-width row flex-center text-dark q-gutter-sm" :style="`height:` + noDataBottomHeightComputed">
@ -206,7 +218,7 @@ import { useQuasar, getCssVar, exportFile } from 'quasar';
import { IconEnum } from '@/platform/enums';
import { extractTableColumnsProps, arrayToMap, OperatorTypeEnum, isEmpty, PageStatusEnum } from '@/platform/components/utils';
import TreeGridRow from './TreeGridRow.vue';
import { mergeProps } from 'vue';
import GridConfig from './GridConfig.vue';
const attrs = useAttrs();
const gc = Environment.getConfigure();
@ -221,16 +233,19 @@ const props = defineProps({
autoFetchData: { type: Boolean, default: true }, //
draggable: { type: Boolean, default: false }, //
pageable: { type: Boolean, default: true }, //
fullScreenButton: { type: Boolean, default: true }, //
configButton: { type: Boolean, default: true }, //
dataUrl: { type: String, default: '' }, // URL
fetchDataUrl: { type: String, default: '' }, // URL
addDataUrl: { type: String, default: '' }, // url
editDataUrl: { type: String, default: '' }, // url
removeDataUrl: { type: String, default: '' }, // url
denseHeader: { type: Boolean, default: false }, //
denseBody: { type: Boolean, default: false }, //
dense: { type: Boolean, default: undefined }, //
denseHeader: { type: Boolean, default: undefined }, //
denseBody: { type: Boolean, default: undefined }, //
denseBottom: { type: Boolean, default: undefined }, //
denseToolbar: { type: Boolean, default: undefined }, // toolbar
sortNo: { type: Boolean, default: false }, //
leftColumnStickyNumber: { type: Number, default: 0 }, // 1-10el
stickyNum: { type: Number, default: 0 }, // 1-10el
checkboxSelection: { type: Boolean, default: true }, // checkbox
tree: { type: Boolean, default: false }, //
treeIcon: { type: Function, default: undefined }, //
@ -540,7 +555,7 @@ const buttonObj = {
.then((resp) => {
table.selected = [];
NotifyManager.info('操作成功');
onRequest({ pagination: table.pagination });
onRequest({ pagination: state.pagination });
})
.catch((error) => {
console.info('error====', error);
@ -642,13 +657,85 @@ const table = reactive({
selected: <any>[],
ticked: <any>[],
spaceHeight: 4,
headerCellHeight: props.denseHeader || attrs.dense ? 24 : 48,
bodyCellHeight: attrs.dense ? 24 : 48,
gridConfig: false,
stickyNum: props.stickyNum,
columns: extractTableColumns,
checkboxSelection: props.checkboxSelection,
sortNo: props.sortNo,
dense: props.dense !== undefined ? props.dense : false,
denseToolbar: props.denseToolbar !== undefined ? props.denseToolbar : false,
denseHeader: props.denseHeader !== undefined ? props.denseHeader : false,
denseBody: props.denseBody !== undefined ? props.denseBody : false,
denseBottom: props.denseBottom !== undefined ? props.denseBottom : false,
queryFormFields: [],
moreQueryStatus: false, //
rows: <any>[],
inFullscreen: false, //
});
provide('table', table);
const denseToolbarComputed = computed(() => {
if (table.denseToolbar) {
return true;
} else if (table.dense !== false) {
return true;
} else {
return false;
}
});
const denseHeaderComputed = computed(() => {
if (table.denseHeader) {
return true;
} else if (table.dense !== false) {
return true;
} else {
return false;
}
});
const denseBodyComputed = computed(() => {
if (table.denseBody) {
return true;
} else if (table.dense !== false) {
return true;
} else {
return false;
}
});
const denseBottomComputed = computed(() => {
if (table.denseBottom) {
return true;
} else if (table.dense !== false) {
return true;
} else {
return false;
}
});
const visibleColumnsComputed = computed(() => {
const visibleColumns: string[] = [];
table.columns.forEach((item) => {
if (!item.hidden && (!props.tree || (props.tree && item.name !== '_sortNo_'))) {
visibleColumns.push(item.name);
}
});
return visibleColumns;
});
const state = reactive({
noDataLabel: '没有可用数据',
loading: false,
loadingLabel: '数据加载中',
queryFormFields: [],
moreQueryStatus: false,
bodyCellHeight: denseBodyComputed.value ? 24 : 48,
//
refHeightWidth: {
yLocation: 0, // Y
topHeight: 0, // top
bottomHeight: 0, // bottom
middleWidth: 0, // middle
middleScrollWidth: 0, // middleWidth
middleHeight: 0, // middle()
columnHeadHeight: 0, //
tableTitleWidth: 0, // title
},
pagination: {
config: {
boundaryLinks: true, //
@ -665,21 +752,7 @@ const table = reactive({
rowsNumber: 10,
rowsPerPageOptions: [5, 10, 20, 50, 100],
},
rows: <any>[],
//
refHeightWidth: {
yLocation: 0, // Y
topHeight: 0, // top
bottomHeight: 0, // bottom
middleWidth: 0, // middle
middleScrollWidth: 0, // middleWidth
middleHeight: 0, // middle()
columnHeadHeight: 0, //
tableTitleWidth: 0, // title
},
inFullscreen: false, //
});
provide('table', table);
const dialog = reactive({
dialogTitle: '新增',
@ -865,9 +938,9 @@ const tableHeightComputed = computed(() => {
const otherHeight = table.spaceHeight || 4;
const resultHeight =
screenHeight -
table.refHeightWidth.yLocation -
(table.refHeightWidth.topHeight || 0) -
(table.refHeightWidth.bottomHeight || 0) -
state.refHeightWidth.yLocation -
(state.refHeightWidth.topHeight || 0) -
(state.refHeightWidth.bottomHeight || 0) -
footerHeight -
mainPaddingBottom -
mainContainerPaddingBottom -
@ -878,7 +951,7 @@ const tableHeightComputed = computed(() => {
};
} else {
return {
height: table.refHeightWidth.middleHeight + 'px',
height: state.refHeightWidth.middleHeight + 'px',
};
}
});
@ -896,9 +969,9 @@ const noDataBottomHeightComputed = computed(() => {
const mainContainerPaddingBottom = gc.theme.main.containerPaddingBottom || 0;
const resultHeight =
screenHeight -
table.refHeightWidth.yLocation -
table.refHeightWidth.topHeight -
table.refHeightWidth.middleHeight -
state.refHeightWidth.yLocation -
state.refHeightWidth.topHeight -
state.refHeightWidth.middleHeight -
mainPaddingBottom -
mainContainerPaddingBottom -
footerHeight -
@ -915,9 +988,9 @@ let tableY = 0;
const tableFullscreenFun = (value) => {
table.inFullscreen = !table.inFullscreen;
if (value) {
tableY = table.refHeightWidth.yLocation;
tableY = state.refHeightWidth.yLocation;
} else {
table.refHeightWidth.yLocation = tableY;
state.refHeightWidth.yLocation = tableY;
tableY = 0;
}
};
@ -943,22 +1016,22 @@ const rowDbClick = (evt, row, index) => {
const onResize = () => {
handlerQueryFormShowField();
if (tableRef.value) {
table.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect().y;
table.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight;
table.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
table.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
table.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
state.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect().y;
state.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight;
state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
// middleHeight
if ((table.rows && table.rows.length > 0) || attrs.hideBottom) {
table.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
} else {
let scrollHeight = 0;
if (table.refHeightWidth.middleScrollWidth - table.refHeightWidth.middleWidth > 0) {
if (state.refHeightWidth.middleScrollWidth - state.refHeightWidth.middleWidth > 0) {
scrollHeight = 15;
}
table.refHeightWidth.middleHeight = table.refHeightWidth.columnHeadHeight + scrollHeight;
state.refHeightWidth.middleHeight = state.refHeightWidth.columnHeadHeight + scrollHeight;
}
table.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth;
state.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth;
}
};
@ -1007,7 +1080,7 @@ const buildQueryEntity = (reqParams) => {
};
const pageChange = (value) => {
table.pagination.page = value;
state.pagination.page = value;
onRequest(table);
};
const requestHandler = async (ops) => {
@ -1034,34 +1107,34 @@ const requestHandler = async (ops) => {
});
const resp = await axios.get(url.fetchDataUrl || url.dataUrl, { params: urlSearchParams }).catch((error) => {
console.info('error-------------', error);
table.loading = false;
state.loading = false;
});
return resp;
};
const onRequest = async (ops: any) => {
table.loading = true;
state.loading = true;
const resp: any = await requestHandler(ops);
table.loading = false;
state.loading = false;
if (resp && resp.data && !props.tree) {
const responseData = resp.data;
if (Array.isArray(responseData)) {
table.rows = responseData;
table.pagination.rowsNumber = responseData.length;
state.pagination.rowsNumber = responseData.length;
} else if (typeof responseData === 'object' && responseData.content) {
if (props.pageable) {
table.pagination.page = table.pagination.reqPageStart === 0 ? responseData.number + 1 : responseData.number;
table.pagination.rowsPerPage = responseData.size || table.pagination.rowsPerPage;
state.pagination.page = state.pagination.reqPageStart === 0 ? responseData.number + 1 : responseData.number;
state.pagination.rowsPerPage = responseData.size || state.pagination.rowsPerPage;
}
table.pagination.rowsNumber = responseData.totalElements;
table.pagination.sortBy = ops.pagination.sortBy;
table.pagination.descending = ops.pagination.descending;
state.pagination.rowsNumber = responseData.totalElements;
state.pagination.sortBy = ops.pagination.sortBy;
state.pagination.descending = ops.pagination.descending;
table.rows = responseData.content;
}
} else if (resp && resp.data && props.tree) {
const responseData = resp.data;
if (Array.isArray(responseData)) {
table.pagination.rowsNumber = responseData.length;
table.pagination.rowsPerPage = 0;
state.pagination.rowsNumber = responseData.length;
state.pagination.rowsPerPage = 0;
if (props.treeRelationship === 'parent') {
const treeRows = TreeBuilder.build(responseData, props.foreignKey, props.primaryKey);
table.rows = treeRows;
@ -1069,8 +1142,8 @@ const onRequest = async (ops: any) => {
table.rows = responseData;
}
} else if (typeof responseData === 'object' && responseData.content) {
table.pagination.rowsNumber = responseData.content.length;
table.pagination.rowsPerPage = 0;
state.pagination.rowsNumber = responseData.content.length;
state.pagination.rowsPerPage = 0;
if (props.treeRelationship === 'parent') {
const treeRows = TreeBuilder.build(responseData.content, props.foreignKey, props.primaryKey);
table.rows = treeRows;
@ -1131,7 +1204,7 @@ const save = async () => {
emit('addEditDataSubmitAfter', resp.data);
NotifyManager.info('操作成功');
dialogRef.value.hide();
onRequest({ pagination: table.pagination });
onRequest({ pagination: state.pagination });
table.selected = [];
})
.catch((error) => {
@ -1292,35 +1365,35 @@ watchEffect(() => {
const refresh = () => {
nextTick(() => {
onRequest({
pagination: table.pagination,
pagination: state.pagination,
});
});
};
const stickyHeaderColumn = () => {
const stickyHeaderColumn = (time = 500) => {
setTimeout(() => {
//
if (tableRef.value) {
table.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect()?.y;
table.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight;
table.refHeightWidth.bottomHeight = tableRef.value.$el.getElementsByClassName('q-table__bottom')[0]?.clientHeight;
table.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
table.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
table.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
table.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth;
state.refHeightWidth.yLocation = tableRef.value.$el.getBoundingClientRect()?.y;
state.refHeightWidth.topHeight = tableRef.value.$el.getElementsByClassName('q-table__top')[0]?.clientHeight;
state.refHeightWidth.bottomHeight = tableRef.value.$el.getElementsByClassName('q-table__bottom')[0]?.clientHeight;
state.refHeightWidth.middleWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientWidth;
state.refHeightWidth.middleScrollWidth = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.scrollWidth;
state.refHeightWidth.columnHeadHeight = tableRef.value.$el.getElementsByTagName('thead')[0]?.clientHeight;
state.refHeightWidth.tableTitleWidth = tableRef.value.$el.getElementsByClassName('_table-title')[0]?.clientWidth;
// middleHeight
if ((table.rows && table.rows.length > 0) || attrs.hideBottom) {
table.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
state.refHeightWidth.middleHeight = tableRef.value.$el.getElementsByClassName('q-table__middle')[0]?.clientHeight;
} else {
let scrollHeight = 0;
if (table.refHeightWidth.middleScrollWidth - table.refHeightWidth.middleWidth > 0) {
if (state.refHeightWidth.middleScrollWidth - state.refHeightWidth.middleWidth > 0) {
scrollHeight = 15;
}
table.refHeightWidth.middleHeight = table.refHeightWidth.columnHeadHeight + scrollHeight;
state.refHeightWidth.middleHeight = state.refHeightWidth.columnHeadHeight + scrollHeight;
}
const tableDom = tableRef.value.$el.getElementsByTagName('table')[0];
if (props.leftColumnStickyNumber > 0) {
if (table.stickyNum > 0) {
if (columnTitleState.columnTitleRowNum > 1) {
const theadDom = tableDom.getElementsByTagName('thead')[0];
const theadTrDom = theadDom.getElementsByTagName('tr');
@ -1385,20 +1458,41 @@ const stickyHeaderColumn = () => {
tableDom.style.setProperty('--row9Height', row9Height + 'px');
}
}
}, 500);
}, time);
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableHeadBgColor', tableHeadBgColor);
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--stickyBgColor', stickyBgColor);
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableBorderColor', tableBorderColor);
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableColumnTitleHeight', table.headerCellHeight + 'px');
// if (props.denseHeader || attrs.dense) {
// }
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableColumnTitleHeight', (denseHeaderComputed.value ? 24 : 48) + 'px');
let headerPadding = '8px';
if (denseHeaderComputed.value) {
headerPadding = '4px';
}
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableHeaderPadding', headerPadding);
let bodyPadding = '8px';
if (denseBodyComputed.value) {
bodyPadding = '4px';
}
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableBodyPadding', bodyPadding);
tableRef.value.$el.getElementsByTagName('table')[0].style.setProperty('--tableBodyHeight', (denseBodyComputed.value ? 24 : 48) + 'px');
if (denseBottomComputed.value) {
tableRef.value.$el.getElementsByClassName('q-table__bottom')[0].style.setProperty('--tableBottomHeight', 33 + 'px');
tableRef.value.$el.getElementsByClassName('q-table__bottom')[0].style.setProperty('--tableBottomButtonHeight', 24 + 'px');
} else {
tableRef.value.$el.getElementsByClassName('q-table__bottom')[0].style.setProperty('--tableBottomHeight', 50 + 'px');
tableRef.value.$el.getElementsByClassName('q-table__bottom')[0].style.setProperty('--tableBottomButtonHeight', 40 + 'px');
}
};
const excludeColumnNum = computed(() => {
let num = 1;
if (props.sortNo) {
let num = 0;
if (props.tree) {
return num;
}
if (table.sortNo) {
num += 1;
}
if (table.checkboxSelection) {
num += 1;
}
return num;
@ -1436,7 +1530,7 @@ const handlerStickyChildrenColumn = (item, columns) => {
};
const getStickyColumn = () => {
const columns = props.columns.filter((item, index) => {
return index < props.leftColumnStickyNumber;
return index < table.stickyNum;
});
const arr = [];
columns.forEach((item) => {
@ -1444,10 +1538,9 @@ const getStickyColumn = () => {
});
return arr;
};
const stickyColumnArr = getStickyColumn();
const moreColumnTitleTableSelectionStyle = computed(() => {
if (props.leftColumnStickyNumber > 0) {
if (table.stickyNum > 0) {
if (props.tree) {
return 'z-index: 3;position: sticky;left: 0px;';
} else {
@ -1457,14 +1550,17 @@ const moreColumnTitleTableSelectionStyle = computed(() => {
return '';
});
const moreColumnTitleTableSortNoStyle = computed(() => {
if (props.sortNo && props.leftColumnStickyNumber > 0) {
return 'z-index: 3;position: sticky;left: var(--columnWidth-1-1);';
if (table.checkboxSelection && table.sortNo && table.stickyNum > 0) {
return 'z-index: 3;position: sticky;left: var(--columnWidth-1-1);width: 50px;';
} else if (table.sortNo && table.stickyNum > 0) {
return 'z-index: 3;position: sticky;left: 0px;width: 50px;';
}
return '';
});
const thStickyLastNameComputed = computed(() => {
let result = <any>[];
const stickyColumnArr = getStickyColumn();
const lastColumn = getMoreRowColumnTitleIndex(stickyColumnArr[stickyColumnArr.length - 1].name);
if (lastColumn.trIndex === 1) {
// 1
@ -1494,8 +1590,9 @@ const thStyleHandler = (c: any, scope: any) => {
}
style = c.style;
}
const stickyColumnArr = getStickyColumn();
if (
props.leftColumnStickyNumber > 0 &&
table.stickyNum > 0 &&
stickyColumnArr.findIndex((item: any) => {
return item.name === c.name;
}) > -1
@ -1604,11 +1701,11 @@ const thStyleHandler = (c: any, scope: any) => {
const tableClassComputed = computed(() => {
const classArr = <string[]>['sticky-header-column-table'];
if (props.leftColumnStickyNumber && props.leftColumnStickyNumber > 0) {
if (table.stickyNum && table.stickyNum > 0) {
if (columnTitleState.columnTitleRowNum > 1) {
//
const stickyColumn = props.columns.filter((item, index) => {
return index < props.leftColumnStickyNumber;
return index < table.stickyNum;
});
let tdNum = excludeColumnNum.value;
stickyColumn.forEach((item: any, index: number) => {
@ -1621,6 +1718,7 @@ const tableClassComputed = computed(() => {
}
}
} else {
console.info('excludeColumnNum======', excludeColumnNum.value);
//
if (excludeColumnNum.value === 2) {
classArr.push('sticky-header-column-table-tr-1' + '-' + 1);
@ -1631,7 +1729,7 @@ const tableClassComputed = computed(() => {
classArr.push('sticky-header-column-table-tr-1' + '-' + 1);
classArr.push('sticky-header-column-table-td-' + 1);
}
for (let i = 1; i <= props.leftColumnStickyNumber; i++) {
for (let i = 1; i <= table.stickyNum; i++) {
classArr.push('sticky-header-column-table-tr-1' + '-' + (i + excludeColumnNum.value));
classArr.push('sticky-header-column-table-td-' + (i + excludeColumnNum.value));
}
@ -1699,10 +1797,10 @@ const onDragLeave = (e) => {
};
//
const onDragOver = (e, scope) => {
if (e.offsetY >= table.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
if (e.offsetY >= state.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
removeDragTopStyle(e);
addDragBottomStyle(e);
} else if (e.offsetY < table.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
} else if (e.offsetY < state.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
removeDragBottomStyle(e);
addDragTopStyle(e);
}
@ -1715,7 +1813,7 @@ const onDrop = (e, scope) => {
return;
}
const dragRow = table.rows[dragRowIndex];
if (e.offsetY < table.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
if (e.offsetY < state.bodyCellHeight / 2 && dragRowIndex !== scope.rowIndex && e.target.parentNode.parentNode.children.length === scope.rowIndex + 1) {
table.rows.splice(dragRowIndex, 1);
table.rows.splice(scope.rowIndex - 1, 0, dragRow);
} else {
@ -1757,7 +1855,7 @@ onMounted(() => {
handlerQueryFormShowField();
if (props.autoFetchData) {
onRequest({
pagination: table.pagination,
pagination: state.pagination,
});
} else {
stickyHeaderColumn();
@ -1839,40 +1937,108 @@ defineExpose({
setAddDataUrl,
setEditDataUrl,
setRemoveDataUrl,
stickyHeaderColumn,
});
const instance = getCurrentInstance();
VueTools.expose2Instance(instance);
</script>
<style scoped lang="css">
:deep(.q-table__top) {
<style lang="css">
/* :deep(.q-table__top) {
padding: 8px 8px;
}
:deep(.q-table th:first-child) {
:deep(.q-table tr:first-child th:first-child) {
border-left: 1px solid var(--tableBorderColor);
}
:deep(.q-table tr td:first-child) {
border-left: 1px solid var(--tableBorderColor);
}
:deep(.q-table th) {
padding: 7px 8px;
background-color: inherit;
:deep(.q-table__middle .q-table th) {
padding: var(--tableHeaderPadding) 8px;
border-left-width: 0px;
border-right-width: 1px;
border-top-width: 0px;
border-bottom-width: 1px;
}
:deep(.q-table__middle .q-table td) {
height: var(--tableBodyHeight);
padding: var(--tableBodyPadding) 8px;
border-left-width: 0px;
border-right-width: 1px;
border-top-width: 0px;
border-bottom-width: 1px;
}
:deep(.q-table__bottom) {
min-height: var(--tableBottomHeight);
}
:deep(.q-table__control .q-field__control) {
min-height: var(--tableBottomButtonHeight);
}
:deep(.q-field__control q-field__append) {
height: var(--tableBottomButtonHeight);
}
:deep(.q-field__control-container .q-field__native) {
min-height: var(--tableBottomButtonHeight);
padding: 0;
}
:deep(.q-field__control .q-field__marginal) {
height: var(--tableBottomButtonHeight);
} */
.q-table__top {
padding: 8px 8px;
}
.q-table tr:first-child th:first-child {
border-left: 1px solid var(--tableBorderColor);
}
.q-table tr td:first-child {
border-left: 1px solid var(--tableBorderColor);
}
.q-table__middle .q-table th {
padding: var(--tableHeaderPadding) 8px;
border-left-width: 0px;
border-right-width: 1px;
border-top-width: 0px;
border-bottom-width: 1px;
}
:deep(.q-table td) {
padding: 7px 8px;
background-color: inherit;
.q-table__middle .q-table td {
height: var(--tableBodyHeight);
padding: var(--tableBodyPadding) 8px;
border-left-width: 0px;
border-right-width: 1px;
border-top-width: 0px;
border-bottom-width: 1px;
}
.q-table__bottom {
min-height: var(--tableBottomHeight);
}
.q-table__control .q-field__control {
min-height: var(--tableBottomButtonHeight);
}
.q-field__control q-field__append {
height: var(--tableBottomButtonHeight);
}
.q-field__control-container .q-field__native {
min-height: var(--tableBottomButtonHeight);
padding: 0;
}
.q-field__control .q-field__marginal {
height: var(--tableBottomButtonHeight);
}
.sticky-header-column-table thead tr {
height: var(--tableColumnTitleHeight);
}

14
io.sc.platform.core.frontend/src/platform/components/toolbar/ChildrenBtn.vue

@ -1,5 +1,5 @@
<template>
<q-item clickable :disable="button[0].enableIf ? !button[0].enableIf(gridProps.selected, gridProps.grid) : false">
<q-item clickable :dense="dense" :disable="button[0].enableIf ? !button[0].enableIf(gridProps.selected, gridProps.grid) : false">
<q-item-section>
<q-item-label><q-icon v-if="button[0].icon" :name="button[0].icon" left size="20px"></q-icon> {{ button[0].label }}</q-item-label>
</q-item-section>
@ -8,16 +8,23 @@
</q-item-section>
<q-menu anchor="top end" self="top start">
<q-list>
<q-list :dense="dense">
<template v-for="(childrenBtn, index) in button" :key="index">
<template v-if="index === 0 && !childrenBtn.click"></template>
<q-separator v-else-if="typeof childrenBtn === 'string' && childrenBtn === 'separator'" />
<ChildrenBtn v-else-if="Array.isArray(childrenBtn) && childrenBtn.length > 0" :button="childrenBtn"></ChildrenBtn>
<ChildrenBtn
v-else-if="Array.isArray(childrenBtn) && childrenBtn.length > 0"
:dense="dense"
:button="childrenBtn"
:grid-props="gridProps"
:button-click="buttonClick"
></ChildrenBtn>
<template v-else>
<q-item
v-close-popup
clickable
:disable="childrenBtn.enableIf ? !childrenBtn.enableIf(gridProps.selected, gridProps.grid) : false"
:dense="dense"
@click="buttonClick(childrenBtn)"
>
<q-item-section>
@ -53,5 +60,6 @@ const props = defineProps({
return () => {};
},
},
dense: { type: Boolean, default: false },
});
</script>

13
io.sc.platform.core.frontend/src/platform/components/toolbar/WToolbar.vue

@ -11,13 +11,14 @@
v-else-if="Array.isArray(btn.data) && btn.data.length > 0"
unelevated
outline
:dense="dense"
v-bind="btn.data[0]"
:split="btn.data[0].click ? true : false"
:disable="btn.data[0].enableIf ? !btn.data[0].enableIf(gridProps.selected, gridProps.grid) : false"
class="class-action-item"
@click="buttonClick(btn.data[0])"
>
<q-list>
<q-list :dense="dense">
<template v-for="(childrenBtn, childrenIndex) in btn.data" :key="'button_c_' + childrenIndex">
<template v-if="childrenIndex === 0"></template>
<template v-else>
@ -27,11 +28,13 @@
:button="childrenBtn"
:grid-props="gridProps"
:button-click="buttonClick"
:dense="dense"
></ChildrenBtn>
<q-item
v-else
v-close-popup
clickable
:dense="dense"
:disable="childrenBtn.enableIf ? !childrenBtn.enableIf(gridProps.selected) : false"
@click="buttonClick(childrenBtn)"
>
@ -48,6 +51,7 @@
:disable="btn.data.enableIf ? !btn.data.enableIf(gridProps.selected, gridProps.grid) : false"
no-wrap
outline
:dense="dense"
v-bind="btn.data"
class="class-action-item"
@click="buttonClick(btn.data)"
@ -55,8 +59,8 @@
</template>
<!-- moreActions -->
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" unelevated outline :label="$t('more')" class="class-action-item">
<q-list>
<q-btn-dropdown v-if="moreActions && moreActions.length > 0" unelevated outline :label="$t('more')" :dense="dense" class="class-action-item">
<q-list :dense="dense">
<template v-for="(childrenBtn, childrenIndex) in moreActions" :key="'moreAction_' + childrenIndex">
<q-separator v-if="typeof childrenBtn.data === 'string' && childrenBtn.data === 'separator'" />
<ChildrenBtn
@ -64,11 +68,13 @@
:button="childrenBtn.data"
:grid-props="gridProps"
:button-click="buttonClick"
:dense="dense"
></ChildrenBtn>
<q-item
v-else
v-close-popup
clickable
:dense="dense"
:disable="childrenBtn.data.enableIf ? !childrenBtn.data.enableIf(gridProps.selected, gridProps.grid) : false"
@click="buttonClick(childrenBtn.data)"
>
@ -94,6 +100,7 @@ const props = defineProps({
xGap: { type: Number, default: 4 }, // x
noIcon: { type: Boolean, default: false }, // icon
align: { type: String, default: 'right' }, //
dense: { type: Boolean, default: false }, //
buttons: {
type: Array,
default: () => {

6
io.sc.platform.core.frontend/src/platform/components/utils/componentComm.ts

@ -276,7 +276,7 @@ function columnChildrenHandler(item: any, gridColumns: any) {
} else {
columnStyle(item);
gridColumns.push({
...{ align: 'left', label: item.name, field: item.name, sortable: true },
...{ align: 'left', label: item.name, field: item.name, sortable: true, hidden: false },
...item,
});
}
@ -287,9 +287,7 @@ function columnChildrenHandler(item: any, gridColumns: any) {
export function extractTableColumnsProps(props: any) {
const gridColumns = <any>[];
if (props.columns && props.columns.length > 0) {
if (props.sortNo && !props.tree) {
gridColumns.push({ name: '_sortNo_', align: 'center', label: '序号', field: '_sortNo_' });
}
gridColumns.push({ name: '_sortNo_', align: 'center', label: '序号', field: '_sortNo_', hidden: props.sortNo ? false : true });
props.columns.forEach((item: any) => {
columnChildrenHandler(item, gridColumns);
});

112
io.sc.platform.core.frontend/src/views/likm/Grid.vue

@ -3,9 +3,8 @@
<w-grid
:title="testGrid.title"
draggable
:dense="true"
:data-url="testGrid.tableDataUrl"
:checkbox-selection="true"
:checkbox-selection="false"
selection="multiple"
:columns="testGrid.tableColumns"
:toolbar-actions="testGrid.toolbar"
@ -13,6 +12,7 @@
:editor="testGrid.addEdit"
:viewer="testGrid.view"
@selection="selection"
@update:selected="aaa"
@row-click="rowClick"
></w-grid>
</div>
@ -27,6 +27,9 @@ import { IconEnum } from '@/platform/enums';
const selection = (details) => {
// console.info('details====', details);
};
const aaa = (newSelected) => {
console.info('newSelected========', newSelected);
};
const startY = ref(0);
const endY = ref(0);
@ -127,74 +130,57 @@ const testGrid = reactive({
// { label: '', name: 'lastModifyDate', type: 'w-date' },
],
tableColumns: [
// {
// name: 'info',
// label: '',
// childrenColumns: [
{
name: 'info',
label: '用户信息',
hidden: true,
childrenColumns: [
{ name: 'loginName', label: '登录名', align: 'right' },
{ name: 'userName', label: '用户名' },
],
},
{
name: 'lxxx',
label: '联系方式',
childrenColumns: [
{ name: 'email', label: '邮箱地址' },
{
name: 'tx',
label: '通讯',
childrenColumns: [
{ name: 'phone', label: '电话' },
{ name: 'mobile', label: '手机号' },
],
},
{ name: 'qq', label: 'QQ' },
],
},
// { name: 'loginName', label: '', align: 'right' },
// { name: 'userName', label: '' },
// ],
// },
// {
// name: 'lxxx',
// label: '',
// childrenColumns: [
// { name: 'email', label: '' },
// {
// name: 'tx',
// label: '',
// childrenColumns: [
// { name: 'phone', label: '' },
// { name: 'mobile', label: '' },
// ],
// },
// { name: 'qq', label: 'QQ' },
// ],
// },
// { name: 'description', label: '', width: 400 },
// {
// name: 'enable',
// label: '',
// align: 'center',
// format: (val, row) => {
{ name: 'description', label: '描述', width: 400 },
{
name: 'enable',
label: '是否可用',
align: 'center',
width: 400,
format: (val, row) => {
// return '1<br/>2';
// // return {
// // _vuecomp_: true,
// // type: EnableIcon,
// // props: {
// // value: val,
// // showNoEnable: true,
// // },
// // };
// // return {
// // _vuecomp_: true,
// // type: 'q-chip',
// // props: {
// // label: val ? '' : '',
// // icon: val ? IconEnum. : IconEnum.,
// // color: val ? 'green' : 'red',
// // },
// // };
// // return {
// // componentsType: 'q-icon',
// // attrs: {
// // name: val ? IconEnum. : IconEnum.,
// // color: val ? 'green' : 'red',
// // size: 'sm',
// // },
// // };
// // return {
// // _vuecomp_: true,
// // type: 'w-text',
// // props: {
// // name: 'aaa',
// // label: '',
// // },
// // };
// },
// },
{ name: 'loginName', label: '登录名', align: 'right' },
{ name: 'userName', label: '用户名' },
return {
componentType: 'q-icon',
attrs: {
name: val ? IconEnum.是状态 : IconEnum.否状态,
color: val ? 'green' : 'red',
size: 'xs',
},
};
},
},
// { name: 'loginName', label: '', align: 'right' },
// { name: 'userName', label: '' },
{ name: 'lastModifier', label: '最后修改人' },
{ name: 'lastModifyDate', label: '最后修改时间' },
],

41
io.sc.platform.core.frontend/src/views/likm/TreeGrid.vue

@ -6,7 +6,6 @@
draggable
sort-no
tree
:dense="true"
:tree-icon="(row) => {}"
:checkbox-selection="true"
:data-url="testGrid.dataUrl"
@ -32,12 +31,12 @@ const { t } = useI18n();
const gridRef = ref();
const rowClick = (evt, row, rowIndex) => {
console.info('evt========', evt);
console.info('row========', row);
console.info('rowIndex========', rowIndex);
// console.info('evt========', evt);
// console.info('row========', row);
// console.info('rowIndex========', rowIndex);
};
const selection = (details) => {
console.info('details====', details);
// console.info('details====', details);
};
const testGrid = {
title: '菜单列表',
@ -96,7 +95,7 @@ const testGrid = {
{
name: 'name',
label: '菜单名称',
width: '50%',
width: 500,
format: (val, row) => {
return t(row.name);
},
@ -104,7 +103,6 @@ const testGrid = {
{
name: 'icon',
label: '图标',
width: '50%',
format: (val, row) => {
return {
componentType: 'q-icon',
@ -115,12 +113,39 @@ const testGrid = {
};
},
},
{ name: 'type', label: '菜单类型' },
// {
// name: 'group',
// label: '',
// childrenColumns: [
// { name: 'type', label: '', width: 500 },
// { name: 'order', label: '' },
// {
// name: 'enable',
// label: '',
// align: 'center',
// width: 200,
// format: (val, row) => {
// return {
// componentType: 'q-icon',
// attrs: {
// name: val ? IconEnum. : IconEnum.,
// color: val ? 'green' : 'red',
// size: 'xs',
// },
// };
// },
// },
// { name: 'lastModifier', label: '' },
// { name: 'lastModifyDate', label: '' },
// ],
// },
{ name: 'type', label: '菜单类型', width: 500 },
{ name: 'order', label: '排序号' },
{
name: 'enable',
label: '是否可用',
align: 'center',
width: 200,
format: (val, row) => {
return {
componentType: 'q-icon',

Loading…
Cancel
Save