Merge pull request '系统配置、系统菜单 VXE table 页面调整' (#33) from shuerchoi/Admin.NET.Pro:main into main

Reviewed-on: http://101.43.53.74:3000/Admin.NET/Admin.NET.Pro/pulls/33
This commit is contained in:
zuohuaijun 2024-07-10 12:55:36 +08:00
commit 3d3c32084d
4 changed files with 192 additions and 121 deletions

View File

@ -8,10 +8,11 @@ import 'vxe-table-plugin-element/dist/style.css';
// Vxe UI 组件库
import VxeUI, { VxeComponentSizeType } from 'vxe-pc-ui';
import ExcelJS from 'exceljs';
import { Local } from '../utils/storage';
import { useThemeConfig } from '/@/stores/themeConfig';
const vxeSize:VxeComponentSizeType = useThemeConfig().themeConfig.globalComponentSize == 'small' ? 'mini'
: useThemeConfig().themeConfig.globalComponentSize == 'default' ? 'small' : 'medium';
export const setupVXETable = (app: App) => {
let vxeSize = getVxeTableSize();
// 加载插件
VxeUITable.use(VXETablePluginElement);
VxeUITable.use(VXETablePluginExportXLSX, { ExcelJS: ExcelJS });
@ -108,19 +109,4 @@ export const setupVXETable = (app: App) => {
// app.config.globalProperties.$XPrint = VxeUI.print
// app.config.globalProperties.$XSaveFile = VxeUI.saveFile
// app.config.globalProperties.$XReadFile = VxeUI.readFile
};
// 从全局主题里面获取组件大小模式
function getVxeTableSize() {
let vxeSize: VxeComponentSizeType = 'mini';
let themeConfig = Local.get('themeConfig');
if (themeConfig == null || themeConfig == undefined) return vxeSize;
let size = themeConfig.globalComponentSize;
if (size == 'large') vxeSize = 'medium';
else if (size == 'default') vxeSize = 'small';
else if (size == 'small') vxeSize = 'mini';
return vxeSize;
}
};

View File

@ -0,0 +1,85 @@
import { dayjs } from 'element-plus';
import { reactive } from 'vue';
import { VxeGridProps, VxeGridPropTypes,VxeComponentSizeType } from 'vxe-table';
import { useThemeConfig } from '/@/stores/themeConfig';
import { merge } from 'lodash-es';
const vxeSize:VxeComponentSizeType = useThemeConfig().themeConfig.globalComponentSize == 'small' ? 'mini'
: useThemeConfig().themeConfig.globalComponentSize == 'default' ? 'small' : 'medium';
/**
* @param {String} id ;
* @param {String} id name:表格名称;
* @param {VxeGridPropTypes.Columns<any>} columns ;
*/
interface iVxeOption {
id?: string;
name?: string;
columns: VxeGridPropTypes.Columns<any>;
}
/**
* Vxe表格参数化Hook
* @param {iVxeOption} opt
* @param {VxeGridProps<RowVO>} extras
* @returns
*/
export const useVxeTable = <T>(opt: iVxeOption, extras?: VxeGridProps<T>) => {
// 默认参数
opt = Object.assign({ enableExport: true, remoteExport: false }, opt);
// 创建tableId,表格id固定才可以记录调整列宽再次刷新仍有效。
opt.id = opt.id ? opt.id : String(new Date().getTime());
// console.log(opt);
const options = reactive<VxeGridProps>({
id: opt.id,
height: 'auto',
autoResize: true,
size: vxeSize,
loading: false,
align: 'center', // 自动监听父元素的变化去重新计算表格(对于父元素可能存在动态变化、显示隐藏的容器中、列宽异常等场景中的可能会用到)
// data: [] as Array<T>,
columns: opt.columns,
toolbarConfig: {
size: vxeSize,
slots: { buttons: 'toolbar_buttons', tools: 'toolbar_tools' },
refresh: {
code: 'query',
},
export: true,
print: true,
zoom: true,
custom: true,
},
checkboxConfig: { range: true },
sortConfig: { trigger: 'cell', remote: true },
exportConfig: {
remote: false, // 设置使用服务端导出
filename: `${opt.name}导出_${dayjs().format('YYMMDDHHmmss')}`,
},
pagerConfig: {
enabled: true,
size: vxeSize,
pageSize: 20,
}, // 分页
printConfig: { sheetName: '' },
proxyConfig: {
enabled: true,
autoLoad: false,
sort: true,
props: {
list: 'data.result', // 不分页时
result: 'data.result.items', // 分页时
total: 'data.result.total',
message: 'data.message',
},
},
customConfig: {
storage: {
// 是否启用 localStorage 本地保存,会将列操作状态保留在本地(需要有 id
visible: true, // 启用显示/隐藏列状态
resizable: true, // 启用列宽状态
},
},
});
return extras ? merge(options, extras) : options;
};

View File

@ -5,12 +5,12 @@
<el-row :gutter="10">
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="配置名称" prop="name">
<el-input v-model="state.queryParams.name" placeholder="配置名称" clearable @keyup.enter.native="handleQuery(true)" />
<el-input v-model="state.queryParams.name" placeholder="配置名称" clearable @keyup.enter.native="handleQuery()" />
</el-form-item>
</el-col>
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
<el-form-item label="配置编码" prop="code">
<el-input v-model="state.queryParams.code" placeholder="配置编码" clearable @keyup.enter.native="handleQuery(true)" />
<el-input v-model="state.queryParams.code" placeholder="配置编码" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
</el-col>
<el-col class="mb5" :xs="24" :sm="12" :md="8" :lg="6" :xl="6">
@ -28,7 +28,7 @@
<el-row>
<el-col>
<el-button-group>
<el-button type="primary" icon="ele-Search" @click="handleQuery(true)" v-auth="'sysConfig:page'" :loading="options.loading"> 查询 </el-button>
<el-button type="primary" icon="ele-Search" @click="handleQuery" v-auth="'sysConfig:page'" :loading="options.loading"> 查询 </el-button>
<el-button icon="ele-Refresh" @click="resetQuery" :loading="options.loading"> 重置 </el-button>
</el-button-group>
</el-col>
@ -36,7 +36,7 @@
</el-card>
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" @sort-change="sortChange" @checkbox-all="handleSelectChange" @checkbox-change="handleSelectChange">
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" v-on="gridEvents">
<template #toolbar_buttons>
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysConfig:add'"> 新增 </el-button>
<!-- <el-button v-if="state.selectList.length > 0" type="danger" icon="ele-Delete" @click="handleBacthDelete" > 批量删除 </el-button> -->
@ -60,15 +60,6 @@
<el-button icon="ele-Delete" text type="danger" v-auth="'sysConfig:delete'" :disabled="row.sysFlag === 1" @click="handleDelete(row)"> </el-button>
</el-tooltip>
</template>
<template #pager>
<vxe-pager
:loading="options.loading"
v-model:current-page="state.tableParams.page"
v-model:page-size="state.tableParams.pageSize"
:total="state.tableParams.total"
@page-change="pageChange"
/>
</template>
</vxe-grid>
</el-card>
@ -79,17 +70,16 @@
<script lang="ts" setup name="sysConfig">
import { onMounted, reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { auth } from '/@/utils/authFunction';
import { VxeGridInstance, VxePagerEvents, VxePagerDefines } from 'vxe-table';
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
import { VxeGridInstance, VxeGridListeners, VxeGridPropTypes } from 'vxe-table';
import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
import EditConfig from '/@/views/system/config/component/editConfig.vue';
import ModifyRecord from '/@/components/table/modifyRecord.vue';
import { getAPI } from '/@/utils/axios-utils';
import { SysConfigApi } from '/@/api-services/api';
import { SysConfig } from '/@/api-services/models';
import { SysConfig, PageConfigInput } from '/@/api-services/models';
import { Local } from '/@/utils/storage';
const xGrid = ref<VxeGridInstance>();
const editConfigRef = ref<InstanceType<typeof EditConfig>>();
const state = reactive({
@ -98,13 +88,9 @@ const state = reactive({
code: undefined,
groupCode: undefined,
},
tableParams: {
page: 1,
pageSize: 50,
field: 'orderNo', //
order: 'aes', //
descStr: 'desc', //
total: 0 as any,
localPageParam: {
pageSize: 20 as number,
defaultSort: { field: 'orderNo', order: 'asc', descStr: 'desc' },
},
visible: false,
title: '',
@ -112,78 +98,84 @@ const state = reactive({
selectList: [] as SysConfig[],
});
//
const localPageParamKey = 'localPageParam:sysConfig';
//
const options = useVxeTable<SysConfig>({
id: 'sysConfig',
name: '参数配置',
columns: [
// { type: 'checkbox', width: 40, fixed: 'left' },
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
{ field: 'name', title: '配置名称', minWidth: 200, showOverflow: 'tooltip', sortable: true },
{ field: 'code', title: '配置编码', minWidth: 200, showOverflow: 'tooltip', sortable: true },
{ field: 'value', title: '属性值', minWidth: 150, showOverflow: 'tooltip', sortable: true },
{ field: 'sysFlag', title: '内置参数', width: 80, showOverflow: 'tooltip', sortable: true, slots: { default: 'row_sysFlag' } },
{ field: 'groupCode', title: '分组编码', minWidth: 120, showOverflow: 'tooltip', sortable: true },
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip', sortable: true },
{ field: 'remark', title: '备注', minWidth: 300, showOverflow: 'tooltip', sortable: true },
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
],
enableExport: auth('sysConfig:export'),
searchCallback: () => handleQuery(),
queryAllCallback: () => fetchData({ pageSize: 99999 }),
});
const options = useVxeTable<SysConfig>(
{
id: 'sysConfig',
name: '参数配置',
columns: [
// { type: 'checkbox', width: 40, fixed: 'left' },
{ type: 'seq', title: '序号', width: 60, fixed: 'left' },
{ field: 'name', title: '配置名称', minWidth: 200, showOverflow: 'tooltip', sortable: true },
{ field: 'code', title: '配置编码', minWidth: 200, showOverflow: 'tooltip', sortable: true },
{ field: 'value', title: '属性值', minWidth: 150, showOverflow: 'tooltip', sortable: true },
{ field: 'sysFlag', title: '内置参数', width: 80, showOverflow: 'tooltip', sortable: true, slots: { default: 'row_sysFlag' } },
{ field: 'groupCode', title: '分组编码', minWidth: 120, showOverflow: 'tooltip', sortable: true },
{ field: 'orderNo', title: '排序', width: 80, showOverflow: 'tooltip', sortable: true },
{ field: 'remark', title: '备注', minWidth: 300, showOverflow: 'tooltip', sortable: true },
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
],
},
// vxeGrid()vxe-table
{
//
proxyConfig: { autoLoad: true, ajax: { query: ({ page, sort }) => handleQueryApi(page, sort) } },
//
sortConfig: { defaultSort: Local.get(localPageParamKey)?.defaultSort || state.localPageParam.defaultSort },
//
pagerConfig: { pageSize: Local.get(localPageParamKey)?.pageSize || state.localPageParam.pageSize },
//
toolbarConfig: { export: false },
}
);
//
onMounted(async () => {
await handleQuery();
state.localPageParam = Local.get(localPageParamKey) || state.localPageParam;
fetchGroupData();
});
//
const handleQuery = async (reset = false) => {
options.loading = true;
if (reset) state.tableParams.page = 1;
var res = await fetchData(null);
xGrid.value?.loadData(res.data.result?.items ?? []);
state.tableParams.total = res.data.result?.total;
state.selectList = [];
options.loading = false;
};
//
const fetchData = async (tableParams: any) => {
let params = Object.assign(state.queryParams, state.tableParams, tableParams);
// api
const handleQueryApi = async (page: VxeGridPropTypes.ProxyAjaxQueryPageParams, sort: VxeGridPropTypes.ProxyAjaxQuerySortCheckedParams) => {
const params = Object.assign(state.queryParams, { page: page.currentPage, pageSize: page.pageSize, field: sort.field, order: sort.order, descStr: 'desc' }) as PageConfigInput;
return getAPI(SysConfigApi).apiSysConfigPagePost(params);
};
//
const handleQuery = async () => {
// vxe-gridcommitProxy(query)
await xGrid.value?.commitProxy('query');
};
const fetchGroupData = async () => {
const res = await getAPI(SysConfigApi).apiSysConfigGroupListGet();
state.groupList = res.data.result ?? [];
};
//
const resetQuery = () => {
const resetQuery = async () => {
state.queryParams.code = undefined;
state.queryParams.name = undefined;
state.queryParams.groupCode = undefined;
handleQuery(true);
// vxe-gridcommitProxy(reload)
await xGrid.value?.commitProxy('reload');
};
//
const pageChange: VxePagerEvents.PageChange = ({ currentPage, pageSize }: VxePagerDefines.PageChangeEventParams) => {
state.tableParams.page = currentPage;
state.tableParams.pageSize = pageSize;
handleQuery();
//
const gridEvents: VxeGridListeners<SysConfig> = {
// pager-config
async pageChange({ pageSize }) {
state.localPageParam.pageSize = pageSize;
Local.set(localPageParamKey, state.localPageParam);
},
//
async sortChange({ field, order }) {
state.localPageParam.defaultSort = { field: field, order: order!, descStr: 'desc' };
Local.set(localPageParamKey, state.localPageParam);
},
};
//
const sortChange = (options: any) => {
state.tableParams.field = options.field;
state.tableParams.order = options.order;
handleQuery();
};
//
const handleAdd = () => {
state.title = '添加配置';

View File

@ -33,7 +33,7 @@
</el-card>
<el-card class="full-table" shadow="hover" style="margin-top: 5px">
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" :tree-config="{}">
<vxe-grid ref="xGrid" class="xGrid-style" v-bind="options" v-on="gridEvents">
<template #toolbar_buttons>
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysMenu:add'"> 新增 </el-button>
<el-button-group style="padding-left: 12px">
@ -77,11 +77,10 @@
</template>
<script lang="ts" setup name="sysMenu">
import { onMounted, reactive, ref } from 'vue';
import { reactive, ref } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { auth } from '/@/utils/authFunction';
import { VxeGridInstance } from 'vxe-table';
import { useVxeTable } from '/@/hooks/vxeTableOptionsHook';
import { VxeGridInstance,VxeGridListeners } from 'vxe-table';
import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
import SvgIcon from '/@/components/svgIcon/index.vue';
import EditMenu from '/@/views/system/menu/component/editMenu.vue';
@ -120,38 +119,47 @@ const options = useVxeTable<SysMenu>(
{ field: '', title: '修改记录', width: 100, showOverflow: 'tooltip', slots: { default: 'row_record' } },
{ title: '操作', fixed: 'right', width: 100, showOverflow: true, slots: { default: 'row_buttons' } },
],
enableExport: auth('sysMenu:export'),
searchCallback: () => handleQuery(),
queryAllCallback: () => fetchData({ pageSize: 99999 }),
},
{ stripe: false, checkboxConfig: { range: false } }
// vxeGrid()vxe-table
{
stripe: false,
checkboxConfig: { range: false },
//
proxyConfig: { autoLoad: true, ajax: { query: () => handleQueryApi() } },
//
pagerConfig: { enabled: false },
//
toolbarConfig: { export: false },
treeConfig: { expandAll: false},
}
);
//
onMounted(async () => {
await handleQuery();
});
//
const handleQuery = async () => {
options.loading = true;
var res = await fetchData(null);
xGrid.value?.loadData(res.data.result ?? []);
state.menuData = res.data.result ?? [];
options.loading = false;
};
//
const fetchData = async (tableParams: any) => {
let params = Object.assign(state.queryParams, tableParams);
// api
const handleQueryApi = async () => {
const params = Object.assign(state.queryParams);
return getAPI(SysMenuApi).apiSysMenuListGet(params.title, params.type);
};
//
const handleQuery = async () => {
// vxe-gridcommitProxy(query)
await xGrid.value?.commitProxy('query')
};
//
const resetQuery = () => {
const resetQuery = async () => {
state.queryParams.title = undefined;
state.queryParams.type = undefined;
handleQuery();
// vxe-gridcommitProxy(reload)
await xGrid.value?.commitProxy('reload')
};
//
const gridEvents: VxeGridListeners<SysMenu> = {
// proxy-config.ajax.query
async proxyQuery() {
state.menuData = xGrid.value?.getTableData().tableData?? []
},
};
//