😎调整菜单管理支持在列表直接修改状态
This commit is contained in:
parent
03978cccce
commit
87cbbba9ac
@ -21,7 +21,7 @@ public enum MenuTypeEnum
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 菜单
|
/// 菜单
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Description("菜单")]
|
[Description("菜单"), Theme("primary")]
|
||||||
Menu = 2,
|
Menu = 2,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@ -198,6 +198,19 @@ public class SysMenuService : IDynamicApiController, ITransient
|
|||||||
await _sysUserMenuService.DeleteMenuList(menuIdList);
|
await _sysUserMenuService.DeleteMenuList(menuIdList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置菜单状态 🔖
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[DisplayName("设置菜单状态")]
|
||||||
|
public async Task<int> SetStatus(BaseStatusInput input)
|
||||||
|
{
|
||||||
|
var menu = await _sysMenuRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
|
||||||
|
menu.Status = input.Status;
|
||||||
|
return await _sysMenuRep.AsUpdateable(menu).UpdateColumns(u => new { u.Status }).ExecuteCommandAsync();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 增加和编辑时检查菜单数据
|
/// 增加和编辑时检查菜单数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -78,8 +78,8 @@
|
|||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"vue-signature-pad": "^3.0.2",
|
"vue-signature-pad": "^3.0.2",
|
||||||
"vue3-tree-org": "^4.2.2",
|
"vue3-tree-org": "^4.2.2",
|
||||||
"vxe-pc-ui": "^4.8.12",
|
"vxe-pc-ui": "^4.8.13",
|
||||||
"vxe-table": "^4.15.5",
|
"vxe-table": "^4.15.6",
|
||||||
"xe-utils": "^3.7.8",
|
"xe-utils": "^3.7.8",
|
||||||
"xlsx-js-style": "^1.2.0"
|
"xlsx-js-style": "^1.2.0"
|
||||||
},
|
},
|
||||||
@ -95,7 +95,7 @@
|
|||||||
"@vitejs/plugin-vue": "^6.0.1",
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
||||||
"@vue/compiler-sfc": "^3.5.18",
|
"@vue/compiler-sfc": "^3.5.18",
|
||||||
"code-inspector-plugin": "^1.0.4",
|
"code-inspector-plugin": "^1.0.5",
|
||||||
"eslint": "^9.33.0",
|
"eslint": "^9.33.0",
|
||||||
"eslint-plugin-vue": "^10.4.0",
|
"eslint-plugin-vue": "^10.4.0",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.3.0",
|
||||||
|
|||||||
@ -18,8 +18,10 @@ import { Configuration } from '../configuration';
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
|
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
|
||||||
import { AddMenuInput } from '../models';
|
import { AddMenuInput } from '../models';
|
||||||
|
import { AdminNETResultInt32 } from '../models';
|
||||||
import { AdminNETResultListMenuOutput } from '../models';
|
import { AdminNETResultListMenuOutput } from '../models';
|
||||||
import { AdminNETResultListSysMenu } from '../models';
|
import { AdminNETResultListSysMenu } from '../models';
|
||||||
|
import { BaseStatusInput } from '../models';
|
||||||
import { DeleteMenuInput } from '../models';
|
import { DeleteMenuInput } from '../models';
|
||||||
import { MenuTypeEnum } from '../models';
|
import { MenuTypeEnum } from '../models';
|
||||||
import { UpdateMenuInput } from '../models';
|
import { UpdateMenuInput } from '../models';
|
||||||
@ -231,6 +233,54 @@ export const SysMenuApiAxiosParamCreator = function (configuration?: Configurati
|
|||||||
options: localVarRequestOptions,
|
options: localVarRequestOptions,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary 设置菜单状态 🔖
|
||||||
|
* @param {BaseStatusInput} [body]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
apiSysMenuSetStatusPost: async (body?: BaseStatusInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||||
|
const localVarPath = `/api/sysMenu/setStatus`;
|
||||||
|
// use dummy base URL string because the URL constructor only accepts absolute URLs.
|
||||||
|
const localVarUrlObj = new URL(localVarPath, 'https://example.com');
|
||||||
|
let baseOptions;
|
||||||
|
if (configuration) {
|
||||||
|
baseOptions = configuration.baseOptions;
|
||||||
|
}
|
||||||
|
const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
|
||||||
|
const localVarHeaderParameter = {} as any;
|
||||||
|
const localVarQueryParameter = {} as any;
|
||||||
|
|
||||||
|
// authentication Bearer required
|
||||||
|
// http bearer authentication required
|
||||||
|
if (configuration && configuration.accessToken) {
|
||||||
|
const accessToken = typeof configuration.accessToken === 'function'
|
||||||
|
? await configuration.accessToken()
|
||||||
|
: await configuration.accessToken;
|
||||||
|
localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
|
||||||
|
|
||||||
|
const query = new URLSearchParams(localVarUrlObj.search);
|
||||||
|
for (const key in localVarQueryParameter) {
|
||||||
|
query.set(key, localVarQueryParameter[key]);
|
||||||
|
}
|
||||||
|
for (const key in options.params) {
|
||||||
|
query.set(key, options.params[key]);
|
||||||
|
}
|
||||||
|
localVarUrlObj.search = (new URLSearchParams(query)).toString();
|
||||||
|
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
|
||||||
|
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
|
||||||
|
const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
|
||||||
|
localVarRequestOptions.data = needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
|
||||||
|
|
||||||
|
return {
|
||||||
|
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||||
|
options: localVarRequestOptions,
|
||||||
|
};
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary 更新菜单 🔖
|
* @summary 更新菜单 🔖
|
||||||
@ -346,6 +396,20 @@ export const SysMenuApiFp = function(configuration?: Configuration) {
|
|||||||
return axios.request(axiosRequestArgs);
|
return axios.request(axiosRequestArgs);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary 设置菜单状态 🔖
|
||||||
|
* @param {BaseStatusInput} [body]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
async apiSysMenuSetStatusPost(body?: BaseStatusInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminNETResultInt32>>> {
|
||||||
|
const localVarAxiosArgs = await SysMenuApiAxiosParamCreator(configuration).apiSysMenuSetStatusPost(body, options);
|
||||||
|
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||||
|
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||||
|
return axios.request(axiosRequestArgs);
|
||||||
|
};
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary 更新菜单 🔖
|
* @summary 更新菜单 🔖
|
||||||
@ -411,6 +475,16 @@ export const SysMenuApiFactory = function (configuration?: Configuration, basePa
|
|||||||
async apiSysMenuLoginMenuTreeGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultListMenuOutput>> {
|
async apiSysMenuLoginMenuTreeGet(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultListMenuOutput>> {
|
||||||
return SysMenuApiFp(configuration).apiSysMenuLoginMenuTreeGet(options).then((request) => request(axios, basePath));
|
return SysMenuApiFp(configuration).apiSysMenuLoginMenuTreeGet(options).then((request) => request(axios, basePath));
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary 设置菜单状态 🔖
|
||||||
|
* @param {BaseStatusInput} [body]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
*/
|
||||||
|
async apiSysMenuSetStatusPost(body?: BaseStatusInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminNETResultInt32>> {
|
||||||
|
return SysMenuApiFp(configuration).apiSysMenuSetStatusPost(body, options).then((request) => request(axios, basePath));
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary 更新菜单 🔖
|
* @summary 更新菜单 🔖
|
||||||
@ -477,6 +551,17 @@ export class SysMenuApi extends BaseAPI {
|
|||||||
public async apiSysMenuLoginMenuTreeGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultListMenuOutput>> {
|
public async apiSysMenuLoginMenuTreeGet(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultListMenuOutput>> {
|
||||||
return SysMenuApiFp(this.configuration).apiSysMenuLoginMenuTreeGet(options).then((request) => request(this.axios, this.basePath));
|
return SysMenuApiFp(this.configuration).apiSysMenuLoginMenuTreeGet(options).then((request) => request(this.axios, this.basePath));
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @summary 设置菜单状态 🔖
|
||||||
|
* @param {BaseStatusInput} [body]
|
||||||
|
* @param {*} [options] Override http request option.
|
||||||
|
* @throws {RequiredError}
|
||||||
|
* @memberof SysMenuApi
|
||||||
|
*/
|
||||||
|
public async apiSysMenuSetStatusPost(body?: BaseStatusInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminNETResultInt32>> {
|
||||||
|
return SysMenuApiFp(this.configuration).apiSysMenuSetStatusPost(body, options).then((request) => request(this.axios, this.basePath));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @summary 更新菜单 🔖
|
* @summary 更新菜单 🔖
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
list: {
|
list: {
|
||||||
|
operationSuccessful: 'Operation successful',
|
||||||
|
operationFailed: 'Operation failed',
|
||||||
menuName: 'Menu Name',
|
menuName: 'Menu Name',
|
||||||
type: 'Type',
|
type: 'Type',
|
||||||
directory: 'Directory',
|
directory: 'Directory',
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
list: {
|
list: {
|
||||||
|
operationSuccessful: '操作成功',
|
||||||
|
operationFailed: '操作失败',
|
||||||
menuName: '菜单名称',
|
menuName: '菜单名称',
|
||||||
type: '类型',
|
type: '类型',
|
||||||
directory: '目录',
|
directory: '目录',
|
||||||
|
|||||||
@ -37,8 +37,8 @@
|
|||||||
<template #toolbar_buttons>
|
<template #toolbar_buttons>
|
||||||
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysMenu/add'"> 新增 </el-button>
|
<el-button type="primary" icon="ele-Plus" @click="handleAdd" v-auth="'sysMenu/add'"> 新增 </el-button>
|
||||||
<el-button-group style="padding-left: 12px">
|
<el-button-group style="padding-left: 12px">
|
||||||
<el-button type="primary" icon="ele-Expand" @click="handleExpand"> 全部展开 </el-button>
|
<el-button icon="ele-Expand" @click="handleExpand"> 全部展开 </el-button>
|
||||||
<el-button type="primary" icon="ele-Fold" @click="handleFold"> 全部折叠 </el-button>
|
<el-button icon="ele-Fold" @click="handleFold"> 全部折叠 </el-button>
|
||||||
</el-button-group>
|
</el-button-group>
|
||||||
</template>
|
</template>
|
||||||
<template #toolbar_tools> </template>
|
<template #toolbar_tools> </template>
|
||||||
@ -50,14 +50,10 @@
|
|||||||
<span class="ml10">{{ $t(row.title) }}</span>
|
<span class="ml10">{{ $t(row.title) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template #row_type="{ row }">
|
<template #row_type="{ row }">
|
||||||
<el-tag type="warning" v-if="row.type === 1">目录</el-tag>
|
<g-sys-dict v-model="row.type" code="MenuTypeEnum" />
|
||||||
<el-tag v-else-if="row.type === 2">菜单</el-tag>
|
|
||||||
<el-tag type="info" v-else>按钮</el-tag>
|
|
||||||
</template>
|
</template>
|
||||||
<template #row_status="{ row }">
|
<template #row_status="{ row }">
|
||||||
<el-tag v-if="row.status === 1 && !row.isHide" type="success">启用</el-tag>
|
<el-switch v-model="row.status" :active-value="1" :inactive-value="2" size="small" @change="changeStatus(row)" />
|
||||||
<el-tag v-if="row.status != 1" type="danger">禁用</el-tag>
|
|
||||||
<el-icon v-if="row.isHide" class="ml5"><Hide /></el-icon>
|
|
||||||
</template>
|
</template>
|
||||||
<template #row_record="{ row }">
|
<template #row_record="{ row }">
|
||||||
<ModifyRecord :data="row" />
|
<ModifyRecord :data="row" />
|
||||||
@ -80,7 +76,6 @@ import { ElMessageBox, ElMessage } from 'element-plus';
|
|||||||
import { VxeGridInstance, VxeGridListeners } from 'vxe-table';
|
import { VxeGridInstance, VxeGridListeners } from 'vxe-table';
|
||||||
import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
|
import { useVxeTable } from '/@/hooks/useVxeTableOptionsHook';
|
||||||
import SvgIcon from '/@/components/svgIcon/index.vue';
|
import SvgIcon from '/@/components/svgIcon/index.vue';
|
||||||
import { Hide } from '@element-plus/icons-vue';
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { auth } from '/@/utils/authFunction';
|
import { auth } from '/@/utils/authFunction';
|
||||||
|
|
||||||
@ -91,6 +86,7 @@ import { getAPI } from '/@/utils/axios-utils';
|
|||||||
import { SysMenuApi } from '/@/api-services/api';
|
import { SysMenuApi } from '/@/api-services/api';
|
||||||
import { SysMenu, UpdateMenuInput } from '/@/api-services/models';
|
import { SysMenu, UpdateMenuInput } from '/@/api-services/models';
|
||||||
|
|
||||||
|
const i18n = useI18n();
|
||||||
const xGrid = ref<VxeGridInstance>();
|
const xGrid = ref<VxeGridInstance>();
|
||||||
const editMenuRef = ref<InstanceType<typeof EditMenu>>();
|
const editMenuRef = ref<InstanceType<typeof EditMenu>>();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
@ -102,8 +98,6 @@ const state = reactive({
|
|||||||
title: '',
|
title: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const i18n = useI18n();
|
|
||||||
|
|
||||||
// 表格参数配置
|
// 表格参数配置
|
||||||
const options = useVxeTable<SysMenu>(
|
const options = useVxeTable<SysMenu>(
|
||||||
{
|
{
|
||||||
@ -111,7 +105,7 @@ const options = useVxeTable<SysMenu>(
|
|||||||
name: i18n.t('message.list.menuInfo'),
|
name: i18n.t('message.list.menuInfo'),
|
||||||
columns: [
|
columns: [
|
||||||
// { type: 'checkbox', width: 40, fixed: 'left' },
|
// { type: 'checkbox', width: 40, fixed: 'left' },
|
||||||
{ field: 'seq', type: 'seq', title: '序号', width: 60, fixed: 'left' },
|
{ field: 'seq', type: 'seq', title: '序号', width: 80, fixed: 'left' },
|
||||||
{ field: 'title', title: '菜单名称', minWidth: 180, showOverflow: 'tooltip', treeNode: true, align: 'left', headerAlign: 'center', slots: { default: 'row_title' } },
|
{ field: 'title', title: '菜单名称', minWidth: 180, showOverflow: 'tooltip', treeNode: true, align: 'left', headerAlign: 'center', slots: { default: 'row_title' } },
|
||||||
{ field: 'type', title: '菜单类型', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_type' } },
|
{ field: 'type', title: '菜单类型', minWidth: 100, showOverflow: 'tooltip', slots: { default: 'row_type' } },
|
||||||
{ field: 'path', title: '路由路径', minWidth: 150, showOverflow: 'tooltip' },
|
{ field: 'path', title: '路由路径', minWidth: 150, showOverflow: 'tooltip' },
|
||||||
@ -222,4 +216,16 @@ const handleExpand = () => {
|
|||||||
const handleFold = () => {
|
const handleFold = () => {
|
||||||
xGrid.value?.clearTreeExpand();
|
xGrid.value?.clearTreeExpand();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 修改状态
|
||||||
|
const changeStatus = async (row: any) => {
|
||||||
|
await getAPI(SysMenuApi)
|
||||||
|
.apiSysMenuSetStatusPost({ id: row.id, status: row.status })
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success(i18n.t('message.list.operationSuccessful'));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
row.status = row.status == 1 ? 2 : 1;
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user