Browse Source

表格优化提交

main
likunming 1 year ago
parent
commit
0f05dc3d41
  1. 6
      io.sc.platform.core.frontend/src/platform/components/grid/TreeGridRow.vue
  2. 58
      io.sc.platform.core.frontend/src/platform/components/grid/WGrid.vue
  3. 2
      io.sc.platform.core.frontend/src/platform/components/panel/WInfoPanel.vue
  4. 27
      io.sc.platform.core.frontend/src/views/likm/QuasarGrid.vue
  5. 223
      io.sc.platform.core.frontend/src/views/likm/TreeGrid.vue

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

@ -1,6 +1,6 @@
<template> <template>
<q-tr :class="row.selected ? 'selected' : ''"> <q-tr :class="row.selected ? 'selected' : ''">
<q-td :style="{ 'padding-left': '2px' }" class="nowrap text-nowrap"> <q-td class="nowrap text-nowrap">
<div class="flex flex-nowrap items-center"> <div class="flex flex-nowrap items-center">
<!--层级占位符--> <!--层级占位符-->
<span :style="`width:${27 * props.level}px;`"></span> <span :style="`width:${27 * props.level}px;`"></span>
@ -92,6 +92,10 @@ const state = reactive({
currRow: {}, currRow: {},
}); });
const tdWidthComputed = computed(() => {
return { width: 100 * props.level + 'px' };
});
watch( watch(
() => props.row.selected, () => props.row.selected,
(newVal, oldVal) => { (newVal, oldVal) => {

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

@ -17,6 +17,7 @@
:loading="table.loading" :loading="table.loading"
:class="tableClassComputed" :class="tableClassComputed"
:table-style="tableHeightComputed" :table-style="tableHeightComputed"
:row-key="rowKey_"
@request="onRequest" @request="onRequest"
@fullscreen="tableFullscreenFun" @fullscreen="tableFullscreenFun"
> >
@ -80,7 +81,7 @@
> >
<q-checkbox v-model="scope.selected" flat <q-checkbox v-model="scope.selected" flat
/></q-th> /></q-th>
<q-th v-else-if="props.checkboxSelection"></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-for="col in scope.cols" :key="col.name" :props="scope" :style="col.style" :class="col.classes">
{{ col.label }} {{ col.label }}
</q-th> </q-th>
@ -199,7 +200,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick, toRaw, useAttrs, getCurrentInstance, provide } from 'vue'; import { ref, reactive, computed, onMounted, nextTick, toRaw, useAttrs, getCurrentInstance, provide, watchEffect } from 'vue';
import { axios, Environment, NotifyManager, TreeBuilder, VueTools, Tools } from '@/platform'; import { axios, Environment, NotifyManager, TreeBuilder, VueTools, Tools } from '@/platform';
import { useQuasar, getCssVar, exportFile } from 'quasar'; import { useQuasar, getCssVar, exportFile } from 'quasar';
import { IconEnum } from '@/platform/enums'; import { IconEnum } from '@/platform/enums';
@ -1008,7 +1009,7 @@ const requestHandler = async (ops) => {
reqParams.page = ops.pagination.page; reqParams.page = ops.pagination.page;
reqParams.size = ops.pagination.rowsPerPage; reqParams.size = ops.pagination.rowsPerPage;
} }
reqParams.pageable = props.pageable; reqParams.pageable = props.tree ? false : props.pageable;
if (ops.pagination.sortBy && ops.pagination.sortBy !== '') { if (ops.pagination.sortBy && ops.pagination.sortBy !== '') {
if (ops.pagination.descending) { if (ops.pagination.descending) {
reqParams.sortBy = '-' + ops.pagination.sortBy; reqParams.sortBy = '-' + ops.pagination.sortBy;
@ -1039,7 +1040,7 @@ const onRequest = async (ops: any) => {
if (Array.isArray(responseData)) { if (Array.isArray(responseData)) {
table.rows = responseData; table.rows = responseData;
table.pagination.rowsNumber = responseData.length; table.pagination.rowsNumber = responseData.length;
} else if (typeof responseData === 'object') { } else if (typeof responseData === 'object' && responseData.content) {
if (props.pageable) { if (props.pageable) {
table.pagination.page = table.pagination.reqPageStart === 0 ? responseData.number + 1 : responseData.number; table.pagination.page = table.pagination.reqPageStart === 0 ? responseData.number + 1 : responseData.number;
table.pagination.rowsPerPage = responseData.size || table.pagination.rowsPerPage; table.pagination.rowsPerPage = responseData.size || table.pagination.rowsPerPage;
@ -1050,10 +1051,26 @@ const onRequest = async (ops: any) => {
table.rows = responseData.content; table.rows = responseData.content;
} }
} else if (resp && resp.data && props.tree) { } else if (resp && resp.data && props.tree) {
const treeRows = TreeBuilder.build(resp.data); const responseData = resp.data;
table.pagination.rowsNumber = resp.data.length; if (Array.isArray(responseData)) {
table.pagination.rowsPerPage = 0; table.pagination.rowsNumber = responseData.length;
table.rows = treeRows; table.pagination.rowsPerPage = 0;
if (props.treeRelationship === 'parent') {
const treeRows = TreeBuilder.build(responseData, props.treeRelationshipField, props.treePrimaryField);
table.rows = treeRows;
} else {
table.rows = responseData;
}
} else if (typeof responseData === 'object' && responseData.content) {
table.pagination.rowsNumber = responseData.content.length;
table.pagination.rowsPerPage = 0;
if (props.treeRelationship === 'parent') {
const treeRows = TreeBuilder.build(responseData.content, props.treeRelationshipField, props.treePrimaryField);
table.rows = treeRows;
} else {
table.rows = responseData.content;
}
}
} }
addRowKey(table.rows); addRowKey(table.rows);
stickyHeaderColumn(); stickyHeaderColumn();
@ -1231,9 +1248,19 @@ const getRows = () => {
return toRaw(table.rows); return toRaw(table.rows);
}; };
watchEffect(() => {
url.dataUrl = props.dataUrl;
url.fetchDataUrl = props.fetchDataUrl;
url.addDataUrl = props.addDataUrl;
url.editDataUrl = props.editDataUrl;
url.removeDataUrl = props.removeDataUrl;
});
const refresh = () => { const refresh = () => {
onRequest({ nextTick(() => {
pagination: table.pagination, onRequest({
pagination: table.pagination,
});
}); });
}; };
@ -1785,13 +1812,24 @@ VueTools.expose2Instance(instance);
:deep(.q-table__top) { :deep(.q-table__top) {
padding: 8px 8px; padding: 8px 8px;
} }
:deep(.q-table 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) { :deep(.q-table th) {
padding: 7px 8px;
background-color: inherit;
border-left-width: 0px; border-left-width: 0px;
border-right-width: 1px; border-right-width: 1px;
border-top-width: 0px; border-top-width: 0px;
border-bottom-width: 1px; border-bottom-width: 1px;
} }
:deep(.q-table td) { :deep(.q-table td) {
padding: 7px 8px;
background-color: inherit;
border-left-width: 0px; border-left-width: 0px;
border-right-width: 1px; border-right-width: 1px;
border-top-width: 0px; border-top-width: 0px;

2
io.sc.platform.core.frontend/src/platform/components/panel/WInfoPanel.vue

@ -11,7 +11,7 @@
<component :is="tdItem.value.componentType" v-bind="tdItem.value.attrs"></component> <component :is="tdItem.value.componentType" v-bind="tdItem.value.attrs"></component>
</template> </template>
<template v-else> <template v-else>
{{ tdItem.value }} <span v-dompurify-html="tdItem.value || ''"></span>
</template> </template>
</td> </td>
</template> </template>

27
io.sc.platform.core.frontend/src/views/likm/QuasarGrid.vue

@ -167,14 +167,17 @@
@row-click=" @row-click="
(evt, row, index) => { (evt, row, index) => {
currentSelectedUserId = row.id; currentSelectedUserId = row.id;
if (roleGridRef) { roleQueryUrl = Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + currentSelectedUserId;
roleGridRef.setFetchDataUrl(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + row.id); orgQueryUrl = Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + currentSelectedUserId;
roleGridRef.refresh(); roleGridRef?.refresh();
} orgTreeGridRef?.refresh();
if (orgTreeGridRef) { // if (roleGridRef) {
orgTreeGridRef.setFetchDataUrl(Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + row.id); // roleGridRef.setFetchDataUrl(Environment.apiContextPath('/api/system/role/queryRolesByUser?userId=') + row.id);
orgTreeGridRef.refresh(); // }
} // if (orgTreeGridRef) {
// orgTreeGridRef.setFetchDataUrl(Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + row.id);
// orgTreeGridRef.refresh();
// }
} }
" "
></w-grid> ></w-grid>
@ -192,7 +195,7 @@
<w-grid <w-grid
ref="roleGridRef" ref="roleGridRef"
:title="$t('system.role.grid.title')" :title="$t('system.role.grid.title')"
:data-url="Environment.apiContextPath('/api/system/role/queryRolesByUser') + currentSelectedUserId" :data-url="roleQueryUrl"
:auto-fetch-data="false" :auto-fetch-data="false"
selection="multiple" selection="multiple"
:full-screen-button="false" :full-screen-button="false"
@ -349,7 +352,7 @@
ref="orgTreeGridRef" ref="orgTreeGridRef"
:tree="true" :tree="true"
:title="$t('system.org.grid.title')" :title="$t('system.org.grid.title')"
:data-url="Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByUser?userId=') + currentSelectedUserId" :data-url="orgQueryUrl"
selection="multiple" selection="multiple"
:full-screen-button="false" :full-screen-button="false"
:toolbar-configure="{ noIcon: true }" :toolbar-configure="{ noIcon: true }"
@ -419,6 +422,7 @@ import SelectRoleDialog from './SelectRoleDialog.vue';
import SetPasswordDialog from './SetPasswordDialog.vue'; import SetPasswordDialog from './SetPasswordDialog.vue';
import UserStatusTag from './UserStatusTag.vue'; import UserStatusTag from './UserStatusTag.vue';
import RoleStatusTag from './RoleStatusTag.vue'; import RoleStatusTag from './RoleStatusTag.vue';
import { nextTick } from 'vue';
const { t } = useI18n(); const { t } = useI18n();
@ -433,6 +437,9 @@ const setPasswordDialogRef = ref();
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom');
const currentSelectedUserId = ref(); const currentSelectedUserId = ref();
const roleQueryUrl = ref('');
const orgQueryUrl = ref('');
const orgConfigure = { const orgConfigure = {
actions: [ actions: [
{ {

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

@ -1,4 +1,4 @@
<template> <!-- <template>
<div> <div>
<w-grid <w-grid
ref="gridRef" ref="gridRef"
@ -6,6 +6,7 @@
draggable draggable
sort-no sort-no
tree tree
:checkbox-selection="false"
:data-url="testGrid.dataUrl" :data-url="testGrid.dataUrl"
:fetch-data-url="testGrid.fetchDataUrl" :fetch-data-url="testGrid.fetchDataUrl"
:columns="testGrid.tableColumns" :columns="testGrid.tableColumns"
@ -128,7 +129,227 @@ const testGrid = {
], ],
}; };
onMounted(() => {
// testGridRef.value.replaceRowsFun([{ typeName: '', typeDesc: '', lastModifier: 'admin', lastModifyDate: '2023-12-26' }]);
});
</script> -->
<template>
<div>
<w-grid
ref="gridRef"
:title="testGrid.title"
draggable
sort-no
:pageable="false"
tree
tree-relationship-field="parentId"
:checkbox-selection="false"
:data-url="testGrid.dataUrl"
:fetch-data-url="testGrid.fetchDataUrl"
:columns="testGrid.tableColumns"
:toolbar-actions="testGrid.toolbar"
:query-form-fields="testGrid.queryFormFields"
:query-form-cols-num="3"
@selection="selection"
></w-grid>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { axios, Environment } from '@/platform';
import EnableIcon from '@/platform/components/grid/EnableIcon.vue';
import { IconEnum } from '@/platform/enums';
const { t } = useI18n();
const gridRef = ref();
const selection = (details) => {
console.info('details====', details);
};
const testGrid = {
title: '菜单列表',
dataUrl: Environment.apiContextPath('api/system/menu'),
fetchDataUrl: Environment.apiContextPath('/api/developer/plugins/parameters'),
toolbar: [
['query', 'separator', 'moreQuery'],
'reset',
'refresh',
'separator',
{
name: 'custBtn',
extend: 'add',
icon: undefined,
label: '自定义按钮',
enableIf: (selected, grid) => {
if (selected && selected.length > 0) {
return true;
}
return false;
},
// beforeClick: (selected, context, grid) => {
// console.info('before');
// context.aaa = '111';
// },
click: (selected, context, _click, grid) => {
_click(selected);
},
afterClick: (selected, context, grid) => {
console.info('=grid==', grid.getEditorForm());
// gridRefs.addEditFormRef.setFieldValue('userName', '');
},
},
[
{
name: 'op',
icon: 'difference',
label: '操作',
},
'add',
'edit',
'clone',
'remove',
'separator',
'view',
'export',
],
'separator',
],
queryFormFields: [
{ label: '菜单名称', name: 'name', type: 'w-password' },
{ label: '菜单类型', name: 'userName', type: 'select' },
{ label: '是否可用', name: 'enable', type: 'select' },
],
tableColumns: [
{
name: 'id',
label: 'id',
},
{
name: 'parentId',
label: 'parentId',
},
{ name: 'code', label: 'code' },
{ name: 'defaultValue', label: 'defaultValue' },
{
name: 'order',
label: 'order',
},
{ name: 'configurationFileUrl', label: 'configurationFileUrl' },
],
};
onMounted(() => { onMounted(() => {
// testGridRef.value.replaceRowsFun([{ typeName: '', typeDesc: '', lastModifier: 'admin', lastModifyDate: '2023-12-26' }]); // testGridRef.value.replaceRowsFun([{ typeName: '', typeDesc: '', lastModifier: 'admin', lastModifyDate: '2023-12-26' }]);
}); });
</script> </script>
<!-- <template>
<div>
<w-grid
ref="gridRef"
:title="testGrid.title"
draggable
sort-no
:pageable="false"
:checkbox-selection="false"
:fetch-data-url="testGrid.fetchDataUrl"
:columns="testGrid.tableColumns"
:toolbar-actions="testGrid.toolbar"
:query-form-fields="testGrid.queryFormFields"
:query-form-cols-num="3"
@selection="selection"
></w-grid>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { useI18n } from 'vue-i18n';
import { axios, Environment } from '@/platform';
import EnableIcon from '@/platform/components/grid/EnableIcon.vue';
import { IconEnum } from '@/platform/enums';
const { t } = useI18n();
const gridRef = ref();
const selection = (details) => {
console.info('details====', details);
};
const testGrid = {
title: '菜单列表',
fetchDataUrl: Environment.apiContextPath('/api/developer/plugins/restartProperties'),
toolbar: [
['query', 'separator', 'moreQuery'],
'reset',
'refresh',
'separator',
{
name: 'custBtn',
extend: 'add',
icon: undefined,
label: '自定义按钮',
enableIf: (selected, grid) => {
if (selected && selected.length > 0) {
return true;
}
return false;
},
// beforeClick: (selected, context, grid) => {
// console.info('before');
// context.aaa = '111';
// },
click: (selected, context, _click, grid) => {
_click(selected);
},
afterClick: (selected, context, grid) => {
console.info('=grid==', grid.getEditorForm());
// gridRefs.addEditFormRef.setFieldValue('userName', '');
},
},
[
{
name: 'op',
icon: 'difference',
label: '操作',
},
'add',
'edit',
'clone',
'remove',
'separator',
'view',
'export',
],
'separator',
],
queryFormFields: [
{ label: '菜单名称', name: 'name', type: 'w-password' },
{ label: '菜单类型', name: 'userName', type: 'select' },
{ label: '是否可用', name: 'enable', type: 'select' },
],
tableColumns: [
{
name: 'id',
label: 'id',
},
{
name: 'parentId',
label: 'parentId',
},
{ name: 'code', label: 'code' },
{ name: 'defaultValue', label: 'defaultValue' },
{
name: 'order',
label: 'order',
},
{ name: 'configurationFileUrl', label: 'configurationFileUrl' },
],
};
onMounted(() => {
// testGridRef.value.replaceRowsFun([{ typeName: '', typeDesc: '', lastModifier: 'admin', lastModifyDate: '2023-12-26' }]);
});
</script> -->

Loading…
Cancel
Save