774 lines
24 KiB
Vue
774 lines
24 KiB
Vue
<template>
|
||
<ArtTableFullScreen>
|
||
<div class="menu-page" id="table-full-screen">
|
||
<!-- 搜索栏 -->
|
||
<ArtSearchBar
|
||
v-model:filter="formFilters"
|
||
:items="formItems"
|
||
:showExpand="false"
|
||
@reset="handleReset"
|
||
@search="handleSearch"
|
||
></ArtSearchBar>
|
||
|
||
<ElCard shadow="never" class="art-table-card">
|
||
<!-- 表格头部 -->
|
||
<ArtTableHeader :showZebra="false" v-model:columns="columnChecks" @refresh="handleRefresh">
|
||
<template #left>
|
||
<el-segmented
|
||
v-model="yearVal"
|
||
size="large"
|
||
:options="segmentedOptions"
|
||
@change="searchArticleByYear"
|
||
>
|
||
<!-- <template #default="scope">
|
||
<div class="flex flex-col items-center gap-2 p-2">
|
||
<div>{{ scope.item.label }}</div>
|
||
</div>
|
||
</template> -->
|
||
</el-segmented>
|
||
<!-- 按钮权限:后端控制模式,使用自定义指令 -->
|
||
<!-- <ElButton
|
||
v-auth="'system@menu_add'"
|
||
@click="showModel('menu', null)"
|
||
v-ripple
|
||
style="margin-left: 20px"
|
||
>
|
||
添加菜单
|
||
</ElButton>
|
||
<ElButton @click="toggleExpand" v-ripple>
|
||
{{ isExpanded ? '收起' : '展开' }}
|
||
</ElButton> -->
|
||
<!-- 按钮权限:前端控制模式,使用 hasAuth 方法 -->
|
||
<!-- <ElButton v-if="hasAuth('B_CODE1')" @click="showModel('menu', null, true)" v-ripple>
|
||
添加菜单
|
||
</ElButton> -->
|
||
</template>
|
||
<template #right>
|
||
<div class="btnadds" @click="showModel('menu', null)" v-auth="'system@menu_add'">
|
||
<i class="iconfont-sys"></i>
|
||
</div>
|
||
</template>
|
||
</ArtTableHeader>
|
||
<!-- 表格 -->
|
||
<ArtTable
|
||
rowKey="path"
|
||
ref="tableRef"
|
||
:loading="loading"
|
||
:data="filteredTableData"
|
||
:marginTop="10"
|
||
:stripe="false"
|
||
>
|
||
<template #default>
|
||
<ElTableColumn v-for="col in columns" :key="col.prop || col.type" v-bind="col" />
|
||
</template>
|
||
</ArtTable>
|
||
|
||
<ElDialog :title="dialogTitle" v-model="dialogVisible" width="700px" align-center>
|
||
<ElForm ref="formRef" :model="form" :rules="rules" label-width="85px">
|
||
<ElRow :gutter="20">
|
||
<ElCol :span="12">
|
||
<ElFormItem label="资源类型" prop="type">
|
||
<el-select v-model="form.type">
|
||
<el-option label="目录" value="directory" />
|
||
<el-option label="菜单" value="menu" />
|
||
<el-option label="权限" value="permission" />
|
||
</el-select>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="12">
|
||
<ElFormItem label="资源名称" prop="name">
|
||
<ElInput v-model="form.name" placeholder="资源名称"></ElInput>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
<ElRow :gutter="20">
|
||
<ElCol :span="12">
|
||
<ElFormItem label="权限标识" prop="code">
|
||
<ElInput v-model="form.code" placeholder="权限标识"></ElInput>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="12">
|
||
<ElFormItem label="图标" prop="icon">
|
||
<ArtIconSelector v-model="form.icon" :iconType="iconType" width="100%" />
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
<ElRow :gutter="20" v-if="form.type !== 'permission'">
|
||
<ElCol :span="12" v-if="form.type !== 'permission'">
|
||
<ElFormItem label="路由地址" prop="url">
|
||
<ElInput v-model="form.url" placeholder="路由地址"></ElInput>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="12">
|
||
<ElFormItem label="打开方式" prop="open_type">
|
||
<ElSelect v-model="form.open_type" class="account-select">
|
||
<el-option label="内部" value="internal" />
|
||
<el-option label="外部" value="external" />
|
||
<el-option label="嵌入" value="iframe" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
<ElRow :gutter="20" v-if="form.type !== 'permission'">
|
||
<ElCol :span="12">
|
||
<ElFormItem label="资源排序" prop="sort" style="width: 100%">
|
||
<ElInputNumber
|
||
v-model="form.sort"
|
||
style="width: 100%"
|
||
@change="handleChange"
|
||
:min="1"
|
||
controls-position="right"
|
||
/>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="12">
|
||
<ElFormItem label="外部链接" prop="link">
|
||
<ElInput
|
||
v-model="form.link"
|
||
placeholder="外部链接/内嵌地址(https://www.baidu.com)"
|
||
></ElInput>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
<ElRow :gutter="20">
|
||
<ElCol :span="12">
|
||
<ElFormItem label="系统" prop="system_id">
|
||
<ElSelect v-model="form.system_id" class="account-select">
|
||
<ElOption
|
||
v-for="account in systemsList"
|
||
:key="account.id"
|
||
:label="account.name"
|
||
:value="account.id"
|
||
>
|
||
<span>{{ account.name }}</span>
|
||
</ElOption>
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="12">
|
||
<ElFormItem label="父级" prop="parent_id">
|
||
<el-tree-select
|
||
v-model="form.parent_id"
|
||
:data="parentList"
|
||
:props="{
|
||
value: 'id',
|
||
label: 'name',
|
||
children: 'children'
|
||
}"
|
||
check-strictly
|
||
:render-after-expand="false"
|
||
style="width: 240px"
|
||
/>
|
||
<!-- <ElSelect v-model="form.parent_id" class="account-select">
|
||
<ElOption
|
||
v-for="account in parentList"
|
||
:key="account.id"
|
||
:label="account.name"
|
||
:value="account.id"
|
||
>
|
||
<span>{{ account.name }}</span>
|
||
</ElOption>
|
||
</ElSelect> -->
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
|
||
<ElRow :gutter="20" v-if="form.type !== 'permission'">
|
||
<ElCol :span="5">
|
||
<ElFormItem label="是否启用" prop="status">
|
||
<ElSwitch v-model="form.status" :active-value="1" :inactive-value="0"></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="5">
|
||
<ElFormItem label="页面缓存" prop="keep_alive">
|
||
<ElSwitch
|
||
v-model="form.keep_alive"
|
||
:active-value="true"
|
||
:inactive-value="false"
|
||
></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="5">
|
||
<ElFormItem label="是否隐藏" prop="is_hide">
|
||
<ElSwitch
|
||
v-model="form.is_hide"
|
||
:active-value="true"
|
||
:inactive-value="false"
|
||
></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="5">
|
||
<ElFormItem label="标签页是否隐藏" prop="is_hide_tab" label-width="120px">
|
||
<ElSwitch
|
||
v-model="form.is_hide_tab"
|
||
:active-value="true"
|
||
:inactive-value="false"
|
||
></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<!-- <ElCol :span="5">
|
||
<ElFormItem label="是否内嵌" prop="isMenu">
|
||
<ElSwitch v-model="form.isIframe"></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol> -->
|
||
</ElRow>
|
||
<ElRow :gutter="20" v-if="form.type !== 'permission'">
|
||
<ElCol :span="5">
|
||
<ElFormItem label="是否首页" prop="is_home">
|
||
<ElSwitch v-model="form.is_home" :active-value="1" :inactive-value="0"></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
<ElCol :span="10">
|
||
<ElFormItem label="不需要认证" prop="no_auth" label-width="120px">
|
||
<ElSwitch v-model="form.no_auth" :active-value="1" :inactive-value="0"></ElSwitch>
|
||
</ElFormItem>
|
||
</ElCol>
|
||
</ElRow>
|
||
</ElForm>
|
||
<template #footer>
|
||
<span class="dialog-footer">
|
||
<ElButton @click="dialogVisible = false">取 消</ElButton>
|
||
<ElButton type="primary" @click="submitForm()">确 定</ElButton>
|
||
</span>
|
||
</template>
|
||
</ElDialog>
|
||
</ElCard>
|
||
</div>
|
||
</ArtTableFullScreen>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { FormInstance, FormRules } from 'element-plus'
|
||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||
import { IconTypeEnum } from '@/enums/appEnum'
|
||
import { formatMenuTitle } from '@/router/utils/utils'
|
||
import ArtButtonTable from '@/components/core/forms/ArtButtonTable.vue'
|
||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||
import { ElPopover, ElButton } from 'element-plus'
|
||
import { AppRouteRecord } from '@/types/router'
|
||
import { useAuth } from '@/composables/useAuth'
|
||
import { SearchFormItem } from '@/types'
|
||
import { systemService } from '@/api/systemApi'
|
||
import { UserService } from '@/api/usersApi'
|
||
const yearVal = ref<any>('')
|
||
defineOptions({ name: 'Menus' })
|
||
|
||
const { hasAuth } = useAuth()
|
||
|
||
// const { menuList } = storeToRefs(useMenuStore())
|
||
const menuList = ref<any[]>([])
|
||
|
||
const loading = ref(false)
|
||
const systemsListtab = ref<any>([])
|
||
const segmentedOptions = computed(() =>
|
||
Array.isArray(systemsListtab.value)
|
||
? systemsListtab.value.map((item: any) => ({ label: item.name, value: item.id }))
|
||
: []
|
||
)
|
||
const getsystemsListtab = async () => {
|
||
const response = await UserService.getsystemsList()
|
||
const list = (response as any)?.data?.records ?? (response as any)?.records ?? response ?? []
|
||
systemsListtab.value = Array.isArray(list) ? list : []
|
||
if (!yearVal.value && systemsListtab.value.length > 0) {
|
||
yearVal.value = systemsListtab.value[0].id
|
||
}
|
||
}
|
||
//系统
|
||
const systemsList = ref<any>()
|
||
const getsystemsList = async () => {
|
||
const response = await UserService.getsystemsList()
|
||
systemsList.value = response || []
|
||
}
|
||
//父级
|
||
const parentList = ref<any>()
|
||
const getparentList = async () => {
|
||
const response = await systemService.getMenuList()
|
||
parentList.value = response || []
|
||
}
|
||
// 定义表单搜索初始值
|
||
const initialSearchState = {
|
||
name: '',
|
||
route: ''
|
||
}
|
||
|
||
// 响应式表单数据
|
||
const formFilters = reactive({ ...initialSearchState })
|
||
|
||
// 增加实际应用的搜索条件状态
|
||
const appliedFilters = reactive({ ...initialSearchState })
|
||
|
||
// 重置表单
|
||
const handleReset = () => {
|
||
Object.assign(formFilters, { ...initialSearchState })
|
||
Object.assign(appliedFilters, { ...initialSearchState })
|
||
getTableData()
|
||
}
|
||
|
||
// 搜索处理
|
||
const handleSearch = () => {
|
||
// 将当前输入的筛选条件应用到实际搜索
|
||
Object.assign(appliedFilters, { ...formFilters })
|
||
getTableData()
|
||
}
|
||
|
||
// 表单配置项
|
||
const formItems: SearchFormItem[] = [
|
||
{
|
||
label: '菜单名称',
|
||
prop: 'name',
|
||
type: 'input',
|
||
config: {
|
||
clearable: true
|
||
}
|
||
},
|
||
{
|
||
label: '路由地址',
|
||
prop: 'route',
|
||
type: 'input',
|
||
config: {
|
||
clearable: true
|
||
}
|
||
}
|
||
]
|
||
|
||
// 构建菜单类型标签
|
||
const buildMenuTypeTag = (row: AppRouteRecord) => {
|
||
if (row.children && row.children.length > 0) {
|
||
return 'info'
|
||
} else if (row.meta?.link && row.meta?.isIframe) {
|
||
return 'success'
|
||
} else if (row.path) {
|
||
return 'primary'
|
||
} else if (row.meta?.link) {
|
||
return 'warning'
|
||
}
|
||
}
|
||
|
||
// 构建菜单类型文本
|
||
const buildMenuTypeText = (row: AppRouteRecord) => {
|
||
if (row.children && row.children.length > 0) {
|
||
return '目录'
|
||
} else if (row.meta?.link && row.meta?.isIframe) {
|
||
return '内嵌'
|
||
} else if (row.path) {
|
||
return '菜单'
|
||
} else if (row.meta?.link) {
|
||
return '外链'
|
||
}
|
||
}
|
||
|
||
// 动态列配置
|
||
const { columnChecks, columns } = useCheckedColumns(() => [
|
||
{
|
||
prop: 'meta.title',
|
||
label: '菜单名称',
|
||
minWidth: 120,
|
||
formatter: (row: AppRouteRecord) => {
|
||
return formatMenuTitle(row.meta?.title)
|
||
}
|
||
},
|
||
{
|
||
prop: 'type',
|
||
label: '菜单类型',
|
||
formatter: (row: AppRouteRecord) => {
|
||
return h(ElTag, { type: buildMenuTypeTag(row) }, () => buildMenuTypeText(row))
|
||
}
|
||
},
|
||
{
|
||
prop: 'path',
|
||
label: '路由',
|
||
formatter: (row: AppRouteRecord) => {
|
||
return row.meta?.link || row.path || ''
|
||
}
|
||
},
|
||
{
|
||
prop: 'meta.authList',
|
||
label: '可操作权限',
|
||
formatter: (row: AppRouteRecord) => {
|
||
return h(
|
||
'div',
|
||
{},
|
||
row.meta.authList?.map((item: { title: string; auth_mark: string }, index: number) => {
|
||
return h(
|
||
ElPopover,
|
||
{
|
||
placement: 'top-start',
|
||
title: '操作',
|
||
width: 200,
|
||
trigger: 'click',
|
||
key: index
|
||
},
|
||
{
|
||
default: () =>
|
||
h('div', { style: 'margin: 0; text-align: right' }, [
|
||
h(
|
||
ElButton,
|
||
{
|
||
size: 'small',
|
||
type: 'primary',
|
||
onClick: () => showModel('button', item, false, row)
|
||
},
|
||
{ default: () => '编辑' }
|
||
),
|
||
h(
|
||
ElButton,
|
||
{
|
||
size: 'small',
|
||
type: 'danger',
|
||
onClick: () => deleteAuth(item)
|
||
},
|
||
{ default: () => '删除' }
|
||
)
|
||
]),
|
||
reference: () => h(ElButton, { class: 'small-btn' }, { default: () => item.title })
|
||
}
|
||
)
|
||
})
|
||
)
|
||
}
|
||
},
|
||
{
|
||
prop: 'date',
|
||
label: '编辑时间',
|
||
formatter: () => '2022-3-12 12:00:00'
|
||
},
|
||
{
|
||
prop: 'status',
|
||
label: '隐藏菜单',
|
||
formatter: (row) => {
|
||
return h(ElTag, { type: row.meta.isHide ? 'danger' : 'info' }, () =>
|
||
row.meta.isHide ? '是' : '否'
|
||
)
|
||
}
|
||
},
|
||
{
|
||
prop: 'operation',
|
||
label: '操作',
|
||
width: 180,
|
||
formatter: (row: AppRouteRecord) => {
|
||
return h('div', [
|
||
// 后端模式权限标识
|
||
hasAuth('system@menu_add') &&
|
||
h(ArtButtonTable, {
|
||
type: 'add',
|
||
onClick: () => showModel('menu', row, true)
|
||
}),
|
||
hasAuth('system@menu_update') &&
|
||
h(ArtButtonTable, {
|
||
type: 'edit',
|
||
onClick: () => showDialog('edit', row)
|
||
}),
|
||
hasAuth('system@menu_destroy') &&
|
||
h(ArtButtonTable, {
|
||
type: 'delete',
|
||
onClick: () => deleteMenu(row)
|
||
})
|
||
])
|
||
}
|
||
}
|
||
])
|
||
|
||
const handleRefresh = () => {
|
||
getTableData()
|
||
}
|
||
|
||
const dialogVisible = ref(false)
|
||
const form = reactive({
|
||
// 菜单
|
||
system_id: '',
|
||
type: 'menu', // 资源类型
|
||
parent_id: '',
|
||
name: '',
|
||
url: '',
|
||
code: '',
|
||
icon: '',
|
||
status: 1,
|
||
sort: 1,
|
||
is_home: 0,
|
||
keep_alive: 1,
|
||
is_hide: 0,
|
||
is_hide_tab: 0,
|
||
no_auth: 0,
|
||
link: '',
|
||
open_type: 'internal'
|
||
})
|
||
const iconType = ref(IconTypeEnum.UNICODE)
|
||
|
||
// const labelPosition = ref('menu')
|
||
const rules = reactive<FormRules>({
|
||
name: [
|
||
{ required: true, message: '请输入菜单名称', trigger: 'blur' },
|
||
{ min: 2, max: 20, message: '长度在 2 到 20 个字符', trigger: 'blur' }
|
||
],
|
||
type: [{ required: true, message: '请选择资源类型', trigger: 'blur' }],
|
||
code: [{ required: true, message: '输入权限标识', trigger: 'blur' }]
|
||
})
|
||
const tableData = ref<AppRouteRecord[]>([])
|
||
|
||
onMounted(() => {
|
||
getsystemsListtab()
|
||
getTableData()
|
||
})
|
||
const searchArticleByYear = () => {
|
||
getTableData()
|
||
}
|
||
// const handleSegmentedClick = (item: any) => {
|
||
// // 若点击的是当前项也强制刷新
|
||
// yearVal.value = item?.value ?? yearVal.value
|
||
// getTableData()
|
||
// }
|
||
const getTableData = async () => {
|
||
loading.value = true
|
||
// 清空旧数据,避免视觉上出现追加
|
||
menuList.value = []
|
||
tableData.value = []
|
||
// 并发安全:本次请求标识
|
||
requestCounter += 1
|
||
const reqId = requestCounter
|
||
const params: any = {
|
||
system_id: yearVal.value || '1'
|
||
}
|
||
try {
|
||
const res = await systemService.getMenutreeList(params)
|
||
// 若在等待过程中又发起了新请求,则丢弃本次结果
|
||
if (reqId !== requestCounter) return
|
||
menuList.value = Array.isArray(res) ? res : []
|
||
} catch (e) {
|
||
console.error(e)
|
||
menuList.value = []
|
||
}
|
||
// console.log(res)
|
||
// menuList.value = data
|
||
|
||
// 基于 appliedFilters 在这里进行过滤,并将结果赋值给 tableData
|
||
const searchName = appliedFilters.name?.toLowerCase().trim() || ''
|
||
const searchRoute = appliedFilters.route?.toLowerCase().trim() || ''
|
||
|
||
const filterMenus = (items: AppRouteRecord[]): AppRouteRecord[] => {
|
||
return items.reduce((acc: AppRouteRecord[], item: AppRouteRecord) => {
|
||
// 浅拷贝节点,避免直接修改原数据
|
||
const copy: AppRouteRecord = { ...item }
|
||
if (copy.children && copy.children.length > 0) {
|
||
copy.children = filterMenus(copy.children)
|
||
}
|
||
|
||
const menuTitle = formatMenuTitle(copy.meta?.title || '').toLowerCase()
|
||
const menuPath = (copy.path || '').toLowerCase()
|
||
const nameMatch = !searchName || menuTitle.includes(searchName)
|
||
const routeMatch = !searchRoute || menuPath.includes(searchRoute)
|
||
const hasChildren = Array.isArray(copy.children) && copy.children.length > 0
|
||
|
||
if (hasChildren || (nameMatch && routeMatch)) {
|
||
acc.push(copy)
|
||
}
|
||
return acc
|
||
}, [])
|
||
}
|
||
|
||
tableData.value = filterMenus(menuList.value)
|
||
loading.value = false
|
||
}
|
||
|
||
// 过滤后的表格数据改为来源于 getTableData 的结果
|
||
const filteredTableData = computed(() => tableData.value)
|
||
|
||
const isEdit = ref(false)
|
||
const formRef = ref<FormInstance>()
|
||
const dialogTitle = computed(() => {
|
||
// const type = labelPosition.value === 'menu' ? '菜单' : '权限'
|
||
return isEdit.value ? `编辑资源` : `新建资源`
|
||
})
|
||
|
||
const showDialog = (type: string, row: AppRouteRecord) => {
|
||
showModel('menu', row)
|
||
}
|
||
|
||
const handleChange = () => {}
|
||
|
||
const submitForm = async () => {
|
||
if (!formRef.value) return
|
||
|
||
await formRef.value.validate(async (valid) => {
|
||
if (valid) {
|
||
try {
|
||
if (isEdit.value) {
|
||
const payload = { ...form, id: itemid.value }
|
||
await systemService.menuEdit(payload as any)
|
||
} else {
|
||
await systemService.menuAdd(form)
|
||
}
|
||
|
||
ElMessage.success(`${isEdit.value ? '编辑' : '新增'}成功`)
|
||
dialogVisible.value = false
|
||
// 刷新表格数据
|
||
getTableData()
|
||
} catch {
|
||
ElMessage.error(`${isEdit.value ? '编辑' : '新增'}失败`)
|
||
}
|
||
}
|
||
})
|
||
}
|
||
const itemid = ref('')
|
||
const showModel = (type: string, row?: any, padd: boolean = false, data?: any) => {
|
||
getsystemsList()
|
||
getparentList()
|
||
dialogVisible.value = true
|
||
// labelPosition.value = type
|
||
isEdit.value = false
|
||
// lockMenuType.value = lock
|
||
resetForm()
|
||
itemid.value = ''
|
||
if (data) {
|
||
isEdit.value = true
|
||
form.type = 'permission'
|
||
form.system_id = data.meta.systemId
|
||
form.parent_id = data.id
|
||
form.name = row.title
|
||
form.code = row.authMark
|
||
itemid.value = row.id
|
||
} else if (padd) {
|
||
nextTick(() => {
|
||
form.parent_id = row.id
|
||
form.system_id = row.meta.systemId
|
||
})
|
||
} else if (row && !padd) {
|
||
isEdit.value = true
|
||
nextTick(() => {
|
||
// 回显数据
|
||
itemid.value = row.id
|
||
form.system_id = row.meta.systemId
|
||
form.parent_id = row.meta.parentId == 0 ? '' : row.meta.parentId
|
||
form.name = row.name
|
||
form.type = row.meta.type
|
||
form.url = row.path
|
||
form.code = row.meta.code
|
||
form.icon = row.meta.icon
|
||
form.sort = row.meta.sort
|
||
form.is_home = row.meta.isHome
|
||
form.keep_alive = row.meta.keepAlive
|
||
form.is_hide = row.meta.isHide
|
||
form.is_hide_tab = row.meta.isHideTab
|
||
form.no_auth = row.meta.noAuth
|
||
form.status = row.meta.status
|
||
form.link = row.meta.link
|
||
form.open_type = row.meta.openType
|
||
})
|
||
}
|
||
}
|
||
|
||
const resetForm = () => {
|
||
formRef.value?.resetFields()
|
||
Object.assign(form, {
|
||
// 菜单
|
||
system_id: '',
|
||
type: 'menu', // 资源类型
|
||
parent_id: '',
|
||
name: '',
|
||
url: '',
|
||
code: '',
|
||
icon: '',
|
||
status: 1,
|
||
sort: 1,
|
||
is_home: 0,
|
||
keep_alive: 1,
|
||
is_hide: 0,
|
||
is_hide_tab: 0,
|
||
no_auth: 0,
|
||
link: '',
|
||
open_type: 'internal'
|
||
})
|
||
}
|
||
|
||
const deleteMenu = async (item: any) => {
|
||
try {
|
||
await ElMessageBox.confirm('确定要删除该菜单吗?删除后无法恢复', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
const res = await systemService.menuDelete({ id: item.id })
|
||
ElMessage.success(res?.message || '删除成功!')
|
||
// 刷新表格数据
|
||
getTableData()
|
||
} catch (error) {
|
||
if (error !== 'cancel') {
|
||
ElMessage.error('删除失败')
|
||
}
|
||
}
|
||
}
|
||
|
||
const deleteAuth = async (item: any) => {
|
||
try {
|
||
await ElMessageBox.confirm('确定要删除该权限吗?删除后无法恢复', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
})
|
||
const res = await systemService.menuDelete({ id: item.id })
|
||
ElMessage.success(res?.message || '删除成功!')
|
||
// 刷新表格数据
|
||
getTableData()
|
||
} catch (error) {
|
||
if (error !== 'cancel') {
|
||
ElMessage.error('删除失败')
|
||
}
|
||
}
|
||
}
|
||
// 添加一个控制变量
|
||
// const lockMenuType = ref(false)
|
||
|
||
const isExpanded = ref(false)
|
||
const tableRef = ref()
|
||
|
||
// 数据请求并发保护计数器
|
||
let requestCounter = 0
|
||
|
||
const toggleExpand = () => {
|
||
isExpanded.value = !isExpanded.value
|
||
nextTick(() => {
|
||
if (tableRef.value) {
|
||
tableRef.value[isExpanded.value ? 'expandAll' : 'collapseAll']()
|
||
}
|
||
})
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.menu-page {
|
||
.svg-icon {
|
||
width: 1.8em;
|
||
height: 1.8em;
|
||
overflow: hidden;
|
||
vertical-align: -8px;
|
||
fill: currentcolor;
|
||
}
|
||
|
||
:deep(.small-btn) {
|
||
height: 22px !important;
|
||
padding: 0 5px !important;
|
||
font-size: 10px !important;
|
||
margin-bottom: 5px;
|
||
}
|
||
:deep(.el-dialog__footer) {
|
||
z-index: inherit;
|
||
.el-button > span {
|
||
z-index: inherit;
|
||
}
|
||
}
|
||
}
|
||
.btnadds {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 32px;
|
||
height: 32px;
|
||
margin-left: 10px;
|
||
color: var(--art-gray-700);
|
||
cursor: pointer;
|
||
background-color: rgba(var(--art-gray-200-rgb), 0.8);
|
||
border-radius: 6px;
|
||
transition: color 0.3s;
|
||
transition: all 0.3s;
|
||
}
|
||
</style>
|