menu change

This commit is contained in:
李远 2026-03-06 18:21:14 +08:00
parent 5e7344500a
commit 2bf41d8fb4
1 changed files with 55 additions and 17 deletions

View File

@ -50,37 +50,35 @@
</div> </div>
</div> </div>
<el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '新增菜单' : '编辑菜单'" width="600px" destroy-on-close> <el-dialog v-model="dialogVisible" :title="dialogType === 'add' ? '新增菜单' : '编辑菜单'" width="600px" destroy-on-close>
<el-form label-width="100px"> <el-form ref="menuFormRef" :model="menuForm" :rules="menuFormRules">
<el-form-item label="菜单名称"> <el-form-item label="菜单名称" prop="name">
<el-input v-model="menuForm.name" placeholder="请输入菜单名称" /> <el-input v-model="menuForm.name" placeholder="请输入菜单名称" />
</el-form-item> </el-form-item>
<el-form-item label="父级菜单"> <el-form-item label="父级菜单" prop="parentId">
<el-select v-model="menuForm.parentId" placeholder="请选择父级菜单" style="width:100%"> <el-select v-model="menuForm.parentId" placeholder="请选择父级菜单" style="width:100%">
<el-option label="一级菜单" value="0" /> <el-option label="一级菜单" value="0" />
<el-option v-for="item in menuTree" :key="item.id" :label="item.name" :value="item.id + ''" /> <el-option v-for="item in menuTree" :key="item.id" :label="item.name" :value="item.id + ''" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="路由路径"> <el-form-item label="路由路径" prop="path">
<el-input v-model="menuForm.path" placeholder="例如:/system/menuList" /> <el-input v-model="menuForm.path" placeholder="例如:/system/menuList" />
</el-form-item> </el-form-item>
<el-form-item label="后端路由"> <el-form-item label="后端路由" prop="api">
<el-input v-model="menuForm.api" placeholder="例如:/api/system/menu/list(可选)" /> <el-input v-model="menuForm.api" placeholder="例如:/api/system/menu/list(可选)" />
</el-form-item> </el-form-item>
<el-form-item label="图标名称"> <el-form-item label="图标名称" prop="icon">
<el-input v-model="menuForm.icon" placeholder="例如:Tools、List" /> <el-input v-model="menuForm.icon" placeholder="例如:Tools、List" />
<div style="margin-top:8px;font-size:12px;color:#909399;">
支持的图标:Tools、List、HomeFilled、UserFilled、Platform、BellFilled、GoodsFilled、WarningFilled
</div>
</el-form-item> </el-form-item>
<el-form-item label="排序"> <el-form-item label="排序" prop="sort">
<el-input-number v-model="menuForm.sort" :min="0" placeholder="数字越小越靠前(默认1)" /> <el-input-number v-model="menuForm.sort" :min="0" placeholder="数字越小越靠前(默认1)" />
</el-form-item> </el-form-item>
<el-form-item label="菜单类型"> <el-form-item label="菜单类型" prop="type">
<el-radio-group v-model="menuForm.type"> <el-radio-group v-model="menuForm.type">
<el-radio :value="1">菜单(显示在侧边栏)</el-radio> <el-radio :value="1">菜单(显示在侧边栏)</el-radio>
<el-radio :value="2">按钮(权限控制)</el-radio> <el-radio :value="2">按钮(权限控制)</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<el-button @click="dialogVisible = false">取消</el-button> <el-button @click="dialogVisible = false">取消</el-button>
@ -90,6 +88,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import { Tools, List, HomeFilled, UserFilled, Platform, BellFilled, GoodsFilled, WarningFilled, Plus } from '@element-plus/icons-vue' import { Tools, List, HomeFilled, UserFilled, Platform, BellFilled, GoodsFilled, WarningFilled, Plus } from '@element-plus/icons-vue'
import { getMenuApi, addMenuApi, deleteMenuApi, editMenuApi } from '@/api/modules/menu' import { getMenuApi, addMenuApi, deleteMenuApi, editMenuApi } from '@/api/modules/menu'
@ -98,9 +97,48 @@ import { getMenuApi, addMenuApi, deleteMenuApi, editMenuApi } from '@/api/module
const menuTree = ref<any[]>([]) const menuTree = ref<any[]>([])
// 定义菜单表单数据 // 定义菜单表单数据
const menuFormRef = ref<FormInstance>()
// 核心:表单验证规则
const menuFormRules = reactive<FormRules>({
// 1. 菜单名称:必填 + 长度限制
name: [
{ required: true, message: '请输入菜单名称', trigger: 'blur' },
{ min: 2, max: 20, message: '菜单名称长度在 2 到 20 个字符之间', trigger: 'blur' }
],
// 2. 父级菜单:必填(默认0,无需手动填)
parentId: [{ required: true, message: '请选择父级菜单', trigger: 'change' }
],
// 3. 路由路径:必填 + 格式校验(以/开头,仅包含字母/数字/下划线/斜杠)
path: [
{ required: true, message: '请输入路由路径', trigger: 'blur' },
{ pattern: /^\/[a-zA-Z0-9_\/]+$/, message: '路由路径必须以/开头,仅包含字母、数字、下划线和斜杠', trigger: 'blur' }
],
// 4. 后端路由:可选,但填了就必须符合格式
api: [
{ required: true, pattern: /(^$)|(^\/[a-zA-Z0-9_\/]+$)/, message: '后端路由若填写,必须以/开头,仅包含字母、数字、下划线和斜杠', trigger: 'blur' }
],
// 5. 图标名称:可选,但填了就必须是指定范围(匹配你提供的图标列表)
icon: [
{
required: true,
pattern: /(^$)|(^Tools$|^List$|^HomeFilled$|^UserFilled$|^Platform$|^BellFilled$|^GoodsFilled$|^WarningFilled$)/
, message: '一级菜单有图标二级菜单没有', trigger: 'blur'
}
],
// 6. 排序:必填 + 数字 + 最小值0
sort: [
{ required: true, message: '请输入排序值', trigger: 'blur' },
{ type: 'number', min: 0, message: '排序值必须是大于等于0的数字', trigger: 'blur' }
],
// 7. 菜单类型:必填(单选框默认1,无需手动选)
type: [
{ required: true, message: '请选择菜单类型', trigger: 'change' },
{ type: 'number', enum: [1, 2], message: '菜单类型只能是1(菜单)或2(按钮)', trigger: 'change' }
]
})
const menuForm = ref({ const menuForm = ref({
name: '', // 菜单名称 name: '', // 菜单名称
parentId: 0, // 默认一级菜单 parentId: '0', // 默认一级菜单
path: '', // 路由路径 path: '', // 路由路径
api: '', // 后端路由 api: '', // 后端路由
icon: '', // 图标名称 icon: '', // 图标名称
@ -151,12 +189,12 @@ const filterEnabledMenus = (menuList: any[]) => {
// 打开新增弹窗 // 打开新增弹窗
const handleAddMenu = () => { const handleAddMenu = () => {
// 清空表单 // 清空表单数据
menuForm.value = { menuForm.value = {
name: '', name: '',
parentId: '', parentId: '0',
path: '', path: '',
api: '', api: '',
icon: '', icon: '',
sort: 1, sort: 1,
type: 1 type: 1
@ -183,8 +221,8 @@ const handleEditMenu = (row: any) => {
// 提交表单(新增/编辑) // 提交表单(新增/编辑)
const handleSubmitMenu = async () => { const handleSubmitMenu = async () => {
//添加校验,校验通过后提交表单
try { try {
await menuFormRef.value?.validate()
if (dialogType.value === 'add') { if (dialogType.value === 'add') {
await addMenuApi({ await addMenuApi({
...menuForm.value, ...menuForm.value,
@ -200,7 +238,7 @@ const handleSubmitMenu = async () => {
} }
dialogVisible.value = false dialogVisible.value = false
} catch (err) { } catch (err) {
ElMessage.error('操作失败') console.log('提交菜单失败', err)
} }
} }