feat(菜单管理): 新建编辑完成
This commit is contained in:
@@ -1,24 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="menu-form-com">
|
<div class="menu-form-com">
|
||||||
<div class="menu-form-alert">
|
<div class="menu-form-alert">
|
||||||
1.红色菜单代表状态禁用;<br />
|
1.红色星号表示必填;<br />
|
||||||
2.添加菜单,如果是目录,组件地址为空即可;<br />
|
2.添加菜单,如果是目录,组件地址为空即可;<br />
|
||||||
3.添加根节点菜单,父级ID为空即可;<br />
|
3.添加根节点菜单,父级菜单为空即可;
|
||||||
4.支持拖拽菜单;
|
|
||||||
</div>
|
</div>
|
||||||
<el-form ref="formRef" :rules="rules" :model="menuFormData" label-width="80px" label-position="right">
|
<el-form ref="formRef" :rules="rules" :model="menuFormData" label-width="80px" label-position="right">
|
||||||
<el-form-item label="菜单名称" prop="name">
|
<el-form-item label="菜单名称" prop="name">
|
||||||
<el-input v-model="menuFormData.name" placeholder="菜单名称" />
|
<el-input v-model="menuFormData.name" placeholder="请输入菜单名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="父级菜单" prop="parent">
|
<el-form-item label="父级菜单" prop="parent">
|
||||||
<!-- <el-input v-model="menuFormData.parent" /> -->
|
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-model="menuFormData.parent"
|
v-model="menuFormData.parent"
|
||||||
:props="defaultTreeProps"
|
:props="defaultTreeProps"
|
||||||
:data="deptDefaultList"
|
:data="deptDefaultList"
|
||||||
lazy
|
lazy
|
||||||
check-strictly
|
check-strictly
|
||||||
|
clearable
|
||||||
:load="handleTreeLoad"
|
:load="handleTreeLoad"
|
||||||
|
placeholder="请选择父级菜单"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@@ -28,45 +28,42 @@
|
|||||||
|
|
||||||
<el-row>
|
<el-row>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="状态">
|
<el-form-item required label="状态">
|
||||||
<el-switch v-model="menuFormData.status" width="60" inline-prompt active-text="启用" inactive-text="禁用" />
|
<el-switch v-model="menuFormData.status" width="60" inline-prompt active-text="启用" inactive-text="禁用" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item v-if="menuFormData.status" label="侧边显示">
|
<el-form-item v-if="menuFormData.status" required label="侧边显示">
|
||||||
<el-switch v-model="menuFormData.visible" width="60" inline-prompt active-text="显示" inactive-text="隐藏" />
|
<el-switch v-model="menuFormData.visible" width="60" inline-prompt active-text="显示" inactive-text="隐藏" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<el-form-item label="菜单状态">
|
<el-row>
|
||||||
<el-radio-group v-model="menuFormData.menu_status">
|
<el-col :span="12">
|
||||||
<el-radio-button label="1">常规</el-radio-button>
|
<el-form-item required label="是否目录">
|
||||||
<el-radio-button label="2">目录</el-radio-button>
|
<el-switch v-model="menuFormData.is_catalog" width="60" inline-prompt active-text="是" inactive-text="否" />
|
||||||
<el-radio-button label="3">外链接</el-radio-button>
|
</el-form-item>
|
||||||
</el-radio-group>
|
</el-col>
|
||||||
</el-form-item>
|
<el-col :span="12">
|
||||||
|
<el-form-item v-if="!menuFormData.is_catalog" required label="外链接">
|
||||||
|
<el-switch v-model="menuFormData.is_link" width="60" inline-prompt active-text="是" inactive-text="否" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
<el-form-item label="备注">
|
<el-form-item label="备注">
|
||||||
<el-input v-model="menuFormData.description" maxlength="200" show-word-limit type="textarea" placeholder="备注" />
|
<el-input v-model="menuFormData.description" maxlength="200" show-word-limit type="textarea" placeholder="请输入备注" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-divider></el-divider>
|
<el-divider></el-divider>
|
||||||
|
|
||||||
<div style="min-height: 184px">
|
<div style="min-height: 184px">
|
||||||
<el-form-item v-if="menuFormData.menu_status === '3'" label="Url">
|
<el-form-item v-if="!menuFormData.is_catalog && !menuFormData.is_link" label="路由地址" prop="web_path">
|
||||||
<el-input v-model="menuFormData.web_path" placeholder="Url" />
|
<el-input v-model="menuFormData.web_path" placeholder="请输入路由地址,请以/开头" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="menuFormData.menu_status === '1'" label="路由地址">
|
<el-form-item v-if="!menuFormData.is_catalog && !menuFormData.is_link" label="组件地址" prop="component">
|
||||||
<el-input v-model="menuFormData.web_path" placeholder="路由地址" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item v-if="menuFormData.menu_status === '1'" label="组件名称">
|
|
||||||
<el-input v-model="menuFormData.component_name" placeholder="组件名称" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item v-if="menuFormData.menu_status === '1'" label="组件地址">
|
|
||||||
<el-autocomplete
|
<el-autocomplete
|
||||||
class="w-full"
|
class="w-full"
|
||||||
v-model="menuFormData.component"
|
v-model="menuFormData.component"
|
||||||
@@ -78,16 +75,24 @@
|
|||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item v-if="menuFormData.menu_status === '1'" label="缓存">
|
<el-form-item v-if="!menuFormData.is_catalog && !menuFormData.is_link" label="组件名称" prop="component_name">
|
||||||
|
<el-input v-model="menuFormData.component_name" placeholder="请输入组件名称" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item v-if="!menuFormData.is_catalog" label="缓存">
|
||||||
<el-switch v-model="menuFormData.cache" width="60" inline-prompt active-text="启用" inactive-text="禁用" />
|
<el-switch v-model="menuFormData.cache" width="60" inline-prompt active-text="启用" inactive-text="禁用" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item v-if="!menuFormData.is_catalog && menuFormData.is_link" label="Url" prop="web_path">
|
||||||
|
<el-input v-model="menuFormData.web_path" placeholder="请输入Url" />
|
||||||
|
</el-form-item>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-divider></el-divider>
|
<el-divider></el-divider>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<div class="menu-form-btns">
|
<div class="menu-form-btns">
|
||||||
<el-button @click="handleSubmit" type="primary">保存</el-button>
|
<el-button @click="handleSubmit" type="primary" :loading="menuBtnLoading">保存</el-button>
|
||||||
<el-button @click="handleCancel">取消</el-button>
|
<el-button @click="handleCancel">取消</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -97,7 +102,8 @@
|
|||||||
import { ref, onMounted, reactive } from 'vue';
|
import { ref, onMounted, reactive } from 'vue';
|
||||||
import { ElForm, FormRules } from 'element-plus';
|
import { ElForm, FormRules } from 'element-plus';
|
||||||
import IconSelector from '/@/components/iconSelector/index.vue';
|
import IconSelector from '/@/components/iconSelector/index.vue';
|
||||||
import { lazyLoadMenu } from '../../api';
|
import { lazyLoadMenu, AddObj, UpdateObj } from '../../api';
|
||||||
|
import { successNotification } from '/@/utils/message';
|
||||||
import { MenuFormDataType, MenuTreeItemType, ComponentFileItem, APIResponseData } from '../../types';
|
import { MenuFormDataType, MenuTreeItemType, ComponentFileItem, APIResponseData } from '../../types';
|
||||||
import type Node from 'element-plus/es/components/tree/src/model/node';
|
import type Node from 'element-plus/es/components/tree/src/model/node';
|
||||||
|
|
||||||
@@ -136,9 +142,10 @@ const emit = defineEmits(['drawerClose']);
|
|||||||
const formRef = ref<InstanceType<typeof ElForm>>();
|
const formRef = ref<InstanceType<typeof ElForm>>();
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
web_path: [{ validator: validateWebPath, trigger: 'blur' }],
|
web_path: [{ required: true, message: '路由地址请以/开头', validator: validateWebPath, trigger: 'blur' }],
|
||||||
name: [{ required: true, message: '菜单名称必填', trigger: 'blur' }],
|
name: [{ required: true, message: '菜单名称必填', trigger: 'blur' }],
|
||||||
parent: [{ required: true, message: '父级菜单必选', trigger: ['blur', 'change'] }],
|
component: [{ required: true, message: '请输入组件地址', trigger: 'blur' }],
|
||||||
|
component_name: [{ required: true, message: '请输入组件名称', trigger: 'blur' }],
|
||||||
});
|
});
|
||||||
|
|
||||||
let deptDefaultList = ref<MenuTreeItemType[]>([]);
|
let deptDefaultList = ref<MenuTreeItemType[]>([]);
|
||||||
@@ -151,10 +158,12 @@ let menuFormData = reactive<MenuFormDataType>({
|
|||||||
cache: true,
|
cache: true,
|
||||||
status: true,
|
status: true,
|
||||||
visible: true,
|
visible: true,
|
||||||
menu_status: '1',
|
|
||||||
component_name: '',
|
component_name: '',
|
||||||
description: '',
|
description: '',
|
||||||
|
is_catalog: false,
|
||||||
|
is_link: false,
|
||||||
});
|
});
|
||||||
|
let menuBtnLoading = ref(false);
|
||||||
|
|
||||||
const setMenuFormData = () => {
|
const setMenuFormData = () => {
|
||||||
if (props.initFormData?.id) {
|
if (props.initFormData?.id) {
|
||||||
@@ -169,6 +178,8 @@ const setMenuFormData = () => {
|
|||||||
menuFormData.cache = props.initFormData?.cache || true;
|
menuFormData.cache = props.initFormData?.cache || true;
|
||||||
menuFormData.component_name = props.initFormData?.component_name || '';
|
menuFormData.component_name = props.initFormData?.component_name || '';
|
||||||
menuFormData.description = props.initFormData?.description || '';
|
menuFormData.description = props.initFormData?.description || '';
|
||||||
|
menuFormData.is_catalog = props.initFormData?.is_catalog || false;
|
||||||
|
menuFormData.is_link = props.initFormData?.is_link || false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -207,7 +218,27 @@ const handleTreeLoad = (node: Node, resolve: Function) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = () => {};
|
const handleSubmit = () => {
|
||||||
|
if (!formRef.value) return;
|
||||||
|
formRef.value.validate(async (valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
try {
|
||||||
|
let res;
|
||||||
|
menuBtnLoading.value = true;
|
||||||
|
if (menuFormData.id) {
|
||||||
|
res = await UpdateObj(menuFormData);
|
||||||
|
} else {
|
||||||
|
res = await AddObj(menuFormData);
|
||||||
|
}
|
||||||
|
if (res?.code === 2000) {
|
||||||
|
successNotification(res.msg as string);
|
||||||
|
handleCancel('submit');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
menuBtnLoading.value = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const handleCancel = (type: string = '') => {
|
const handleCancel = (type: string = '') => {
|
||||||
emit('drawerClose', type);
|
emit('drawerClose', type);
|
||||||
|
|||||||
@@ -56,7 +56,8 @@ export interface MenuFormDataType {
|
|||||||
cache: boolean;
|
cache: boolean;
|
||||||
status: boolean;
|
status: boolean;
|
||||||
visible: boolean;
|
visible: boolean;
|
||||||
menu_status: string;
|
|
||||||
component_name: string;
|
component_name: string;
|
||||||
description: string;
|
description: string;
|
||||||
|
is_catalog: boolean;
|
||||||
|
is_link: boolean;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user