|
|
|
@@ -41,82 +41,78 @@
|
|
|
|
|
<el-col :span="1.5">
|
|
|
|
|
<el-button type="info" plain icon="Sort" @click="toggleExpandAll">{{ $t('btn.expand') }}/{{ $t('btn.collapse') }}</el-button>
|
|
|
|
|
</el-col>
|
|
|
|
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
|
|
|
|
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
|
|
<el-table
|
|
|
|
|
v-if="refreshTable"
|
|
|
|
|
v-loading="loading"
|
|
|
|
|
:data="menuList"
|
|
|
|
|
row-key="menuId"
|
|
|
|
|
:default-expand-all="isExpandAll"
|
|
|
|
|
border
|
|
|
|
|
lazy
|
|
|
|
|
<vxe-table
|
|
|
|
|
:height="tableHeight"
|
|
|
|
|
show-overflow
|
|
|
|
|
ref="listRef"
|
|
|
|
|
:load="loadMenu"
|
|
|
|
|
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
|
|
|
|
|
<el-table-column prop="menuName" :label="$t('m.menuName')" :show-overflow-tooltip="true" width="160">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<span v-if="scope.row.menuNameKey">
|
|
|
|
|
{{ $t(scope.row.menuNameKey) }}
|
|
|
|
|
</span>
|
|
|
|
|
<span v-else>
|
|
|
|
|
{{ scope.row.menuName }}
|
|
|
|
|
</span>
|
|
|
|
|
:loading="loading"
|
|
|
|
|
:column-config="{ resizable: true }"
|
|
|
|
|
:tree-config="{
|
|
|
|
|
parentField: 'parentId',
|
|
|
|
|
reserve: true
|
|
|
|
|
}"
|
|
|
|
|
:row-config="{
|
|
|
|
|
keyField: 'menuId'
|
|
|
|
|
}"
|
|
|
|
|
:scroll-y="{ enabled: true, gt: 20 }"
|
|
|
|
|
:data="menuList">
|
|
|
|
|
<vxe-column field="menuName" :title="$t('m.menuName')" tree-node width="160"> </vxe-column>
|
|
|
|
|
<vxe-column field="menuId" :title="$t('m.menuid')" width="90"></vxe-column>
|
|
|
|
|
<vxe-column field="icon" :title="$t('m.icon')" align="center" width="60">
|
|
|
|
|
<template #default="{ row }">
|
|
|
|
|
<svg-icon :name="row.icon"></svg-icon>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="icon" :label="$t('m.icon')" align="center" width="60">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column field="menuType" :title="$t('m.menuType')" align="center" width="80">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<svg-icon :name="scope.row.icon" />
|
|
|
|
|
<el-tag :disable-transitions="true" type="danger" v-if="scope.row.menuType == 'M' && scope.row.isFrame == 1">{{ $t('m.link') }}</el-tag>
|
|
|
|
|
<el-tag :disable-transitions="true" v-else-if="scope.row.menuType == 'C'">{{ $t('m.menu') }}</el-tag>
|
|
|
|
|
<el-tag :disable-transitions="true" type="success" v-else-if="scope.row.menuType == 'M'">{{ $t('m.directory') }}</el-tag>
|
|
|
|
|
<el-tag :disable-transitions="true" type="warning" v-else-if="scope.row.menuType == 'F'">{{ $t('m.button') }}</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="menuId" :label="$t('m.menuid')" :show-overflow-tooltip="true" width="80" align="center"></el-table-column>
|
|
|
|
|
<el-table-column prop="menuType" :label="$t('m.menuType')" align="center" width="80">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column field="orderNum" :title="$t('m.sort')" width="90" sortable align="center" v-if="columns.showColumn('orderNum')">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-tag type="danger" v-if="scope.row.menuType == 'M' && scope.row.isFrame == 1">{{ $t('m.link') }}</el-tag>
|
|
|
|
|
<el-tag v-else-if="scope.row.menuType == 'C'">{{ $t('m.menu') }}</el-tag>
|
|
|
|
|
<el-tag type="success" v-else-if="scope.row.menuType == 'M'">{{ $t('m.directory') }}</el-tag>
|
|
|
|
|
<el-tag type="warning" v-else-if="scope.row.menuType == 'F'">{{ $t('m.button') }}</el-tag>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="orderNum" :label="$t('m.sort')" width="90" sortable align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<span v-show="editIndex != scope.$index" @click="editCurrRow(scope.$index)">{{ scope.row.orderNum }}</span>
|
|
|
|
|
<span v-show="editIndex != scope.row.menuId" @click="editCurrRow(scope.row.menuId)">{{ scope.row.orderNum }}</span>
|
|
|
|
|
<el-input
|
|
|
|
|
:ref="setColumnsRef"
|
|
|
|
|
v-show="editIndex == scope.$index"
|
|
|
|
|
v-show="editIndex == scope.row.menuId"
|
|
|
|
|
v-model="scope.row.orderNum"
|
|
|
|
|
@blur="handleChangeSort(scope.row)"></el-input>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="perms" :label="$t('m.authorityID')" :show-overflow-tooltip="true"></el-table-column>
|
|
|
|
|
<el-table-column prop="component" :label="$t('m.componentPath')" :show-overflow-tooltip="true"></el-table-column>
|
|
|
|
|
<el-table-column prop="visible" :label="$t('m.isShow')" width="70" align="center">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column field="perms" :title="$t('m.authorityID')" show-overflow="title"></vxe-column>
|
|
|
|
|
<vxe-column field="component" :title="$t('m.componentPath')" show-overflow></vxe-column>
|
|
|
|
|
<vxe-column field="visible" :title="$t('m.isShow')" width="90" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="sys_show_hide" :value="scope.row.visible" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column prop="status" :label="$t('m.menuState')" width="80" align="center">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column field="status" :title="$t('m.menuState')" width="80" align="center">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="$t('common.addTime')" align="center" prop="createTime" :show-overflow-tooltip="true">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column :title="$t('common.addTime')" align="center" field="createTime" show-overflow v-if="columns.showColumn('createTime')">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
<el-table-column :label="$t('btn.operate')" align="center" width="170" class-name="small-padding fixed-width">
|
|
|
|
|
</vxe-column>
|
|
|
|
|
<vxe-column :title="$t('btn.operate')" align="center" width="140">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-button-group>
|
|
|
|
|
<el-button text size="small" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:menu:edit']"></el-button>
|
|
|
|
|
<el-button text size="small" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['system:menu:add']"></el-button>
|
|
|
|
|
<el-button text size="small" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:menu:remove']"></el-button>
|
|
|
|
|
</el-button-group>
|
|
|
|
|
</template>
|
|
|
|
|
</el-table-column>
|
|
|
|
|
</el-table>
|
|
|
|
|
</vxe-column>
|
|
|
|
|
</vxe-table>
|
|
|
|
|
|
|
|
|
|
<!-- 添加或修改菜单对话框 -->
|
|
|
|
|
<el-dialog :title="title" v-model="open" width="680px" append-to-body draggable>
|
|
|
|
|
<el-dialog :title="title" v-model="open" width="720px" append-to-body>
|
|
|
|
|
<el-form ref="menuRef" :model="form" :rules="rules" label-width="100px">
|
|
|
|
|
<el-row>
|
|
|
|
|
<el-col :lg="24">
|
|
|
|
@@ -164,17 +160,11 @@
|
|
|
|
|
<el-input v-model="form.menuNameKey" placeholder="请输入菜单key" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :lg="12">
|
|
|
|
|
<el-form-item :label="$t('m.sort')" prop="orderNum">
|
|
|
|
|
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :lg="24" v-if="form.menuType != 'F'">
|
|
|
|
|
<el-col :lg="12" v-if="form.menuType != 'F'">
|
|
|
|
|
<el-form-item :label="$t('m.icon')" prop="icon">
|
|
|
|
|
<!-- :visible="showChooseIcon" -->
|
|
|
|
|
<el-popover placement="bottom-start" :teleported="false" :width="540" trigger="click">
|
|
|
|
|
<el-popover placement="bottom-start" :width="540" trigger="click">
|
|
|
|
|
<template #reference>
|
|
|
|
|
<el-input v-model="form.icon" placeholder="点击选择图标" @click="showSelectIcon" readonly>
|
|
|
|
|
<el-input v-model="form.icon" placeholder="点击选择图标" readonly>
|
|
|
|
|
<template #prefix>
|
|
|
|
|
<svg-icon v-if="form.icon" :name="form.icon" />
|
|
|
|
|
<el-icon v-else>
|
|
|
|
@@ -187,6 +177,11 @@
|
|
|
|
|
</el-popover>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :lg="12">
|
|
|
|
|
<el-form-item :label="$t('m.sort')" prop="orderNum">
|
|
|
|
|
<el-input-number v-model="form.orderNum" controls-position="right" :min="0" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :lg="12" v-if="form.menuType != 'F'">
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<template #label>
|
|
|
|
@@ -232,7 +227,11 @@
|
|
|
|
|
{{ $t('m.componentPath') }}
|
|
|
|
|
</span>
|
|
|
|
|
</template>
|
|
|
|
|
<el-input v-model="form.component" placeholder="请输入组件路径" />
|
|
|
|
|
<el-input v-model="form.component" placeholder="请输入组件路径">
|
|
|
|
|
<template #prepend>
|
|
|
|
|
<span style="width: 40px">src/views/</span>
|
|
|
|
|
</template>
|
|
|
|
|
</el-input>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-col>
|
|
|
|
|
<el-col :lg="12" v-if="form.menuType != 'M'">
|
|
|
|
@@ -329,7 +328,6 @@
|
|
|
|
|
import { addMenu, delMenu, getMenu, listMenu, updateMenu, changeMenuSort as changeSort, listMenuById } from '@/api/system/menu'
|
|
|
|
|
import SvgIcon from '@/components/SvgIcon'
|
|
|
|
|
import IconSelect from '@/components/IconSelect'
|
|
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance()
|
|
|
|
|
|
|
|
|
|
var dictParams = [{ dictType: 'sys_show_hide' }, { dictType: 'sys_normal_disable' }]
|
|
|
|
@@ -341,12 +339,9 @@ const title = ref('')
|
|
|
|
|
const menuOptions = ref([])
|
|
|
|
|
const menuQueryOptions = ref([])
|
|
|
|
|
const isExpandAll = ref(false)
|
|
|
|
|
const refreshTable = ref(true)
|
|
|
|
|
const showChooseIcon = ref(false)
|
|
|
|
|
const iconSelectRef = ref(null)
|
|
|
|
|
const menuRef = ref(null)
|
|
|
|
|
const listRef = ref(null)
|
|
|
|
|
const loadNodeMap = new Map()
|
|
|
|
|
const state = reactive({
|
|
|
|
|
form: {},
|
|
|
|
|
queryParams: {
|
|
|
|
@@ -361,7 +356,7 @@ const state = reactive({
|
|
|
|
|
orderNum: [{ required: true, message: '菜单顺序不能为空', trigger: 'blur' }],
|
|
|
|
|
path: [
|
|
|
|
|
{ required: true, message: '路由地址不能为空', trigger: 'blur' },
|
|
|
|
|
{ pattern: /^[A-Za-z].+$/, message: '输入格式不正确,字母开头', trigger: 'blur' }
|
|
|
|
|
{ pattern: /^[/A-Za-z].+$/, message: '输入格式不正确,字母开头', trigger: 'blur' }
|
|
|
|
|
],
|
|
|
|
|
visible: [{ required: true, message: '显示状态不能为空', trigger: 'blur' }]
|
|
|
|
|
},
|
|
|
|
@@ -374,19 +369,28 @@ proxy.getDicts(dictParams).then((response) => {
|
|
|
|
|
state[element.dictType] = element.list
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
// 列显隐信息
|
|
|
|
|
const columns = ref([
|
|
|
|
|
{ label: `添加时间`, visible: false, prop: 'createTime' },
|
|
|
|
|
{ label: `排序`, visible: false, prop: 'orderNum' }
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
const tableHeight = ref(document.documentElement.scrollHeight - 245 + 'px')
|
|
|
|
|
const { queryParams, form, rules, sys_show_hide, sys_normal_disable } = toRefs(state)
|
|
|
|
|
|
|
|
|
|
/** 查询菜单列表 */
|
|
|
|
|
function getList() {
|
|
|
|
|
function getList(type) {
|
|
|
|
|
loading.value = true
|
|
|
|
|
if (queryParams.value.parentId != undefined || queryParams.value.menuName != undefined) {
|
|
|
|
|
queryParams.value.menuTypeIds = ''
|
|
|
|
|
} else {
|
|
|
|
|
queryParams.value.menuTypeIds = 'M,C'
|
|
|
|
|
queryParams.value.menuTypeIds = 'M,C,F'
|
|
|
|
|
}
|
|
|
|
|
listMenu(queryParams.value).then((response) => {
|
|
|
|
|
menuList.value = response.data
|
|
|
|
|
if (type == 1) {
|
|
|
|
|
menuQueryOptions.value = response.data
|
|
|
|
|
}
|
|
|
|
|
loading.value = false
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
@@ -417,15 +421,10 @@ function reset() {
|
|
|
|
|
}
|
|
|
|
|
proxy.resetForm('menuRef')
|
|
|
|
|
}
|
|
|
|
|
/** 展示下拉图标 */
|
|
|
|
|
function showSelectIcon() {
|
|
|
|
|
iconSelectRef.value.reset()
|
|
|
|
|
// showChooseIcon.value = true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** 选择图标 */
|
|
|
|
|
function selected(name) {
|
|
|
|
|
form.value.icon = name
|
|
|
|
|
// showChooseIcon.value = false
|
|
|
|
|
}
|
|
|
|
|
/** 搜索按钮操作 */
|
|
|
|
|
function handleQuery() {
|
|
|
|
@@ -450,11 +449,26 @@ function handleAdd(row) {
|
|
|
|
|
}
|
|
|
|
|
/** 展开/折叠操作 */
|
|
|
|
|
function toggleExpandAll() {
|
|
|
|
|
refreshTable.value = false
|
|
|
|
|
// refreshTable.value = false
|
|
|
|
|
isExpandAll.value = !isExpandAll.value
|
|
|
|
|
nextTick(() => {
|
|
|
|
|
refreshTable.value = true
|
|
|
|
|
})
|
|
|
|
|
// nextTick(() => {
|
|
|
|
|
// refreshTable.value = true
|
|
|
|
|
// })
|
|
|
|
|
const $table = listRef.value
|
|
|
|
|
if ($table) {
|
|
|
|
|
if (isExpandAll.value) {
|
|
|
|
|
$table.setAllTreeExpand(true)
|
|
|
|
|
} else {
|
|
|
|
|
$table.clearTreeExpand()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const hasExpandRow = (row) => {
|
|
|
|
|
const $table = listRef.value
|
|
|
|
|
if ($table) {
|
|
|
|
|
return $table.isTreeExpandByRow(row)
|
|
|
|
|
}
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
/** 修改按钮操作 */
|
|
|
|
|
async function handleUpdate(row) {
|
|
|
|
@@ -535,27 +549,11 @@ function handleChangeSort(info) {
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// ******************自定义编辑 end **********************
|
|
|
|
|
const loadMenu = (row, treeNode, resolve) => {
|
|
|
|
|
listMenuById(row.menuId).then((res) => {
|
|
|
|
|
loadNodeMap.set(row.menuId, { row, treeNode, resolve })
|
|
|
|
|
resolve(res.data)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
// 刷新懒加载后的数据
|
|
|
|
|
function refreshMenu(pid) {
|
|
|
|
|
loading.value = true
|
|
|
|
|
// console.log(loadNodeMap)
|
|
|
|
|
if (loadNodeMap.size > 0) {
|
|
|
|
|
const hasNode = loadNodeMap.has(pid)
|
|
|
|
|
if (hasNode) {
|
|
|
|
|
const { row, treeNode, resolve } = loadNodeMap.get(pid)
|
|
|
|
|
proxy.$refs.listRef.store.states.lazyTreeNodeMap[pid] = []
|
|
|
|
|
loadMenu(row, treeNode, resolve)
|
|
|
|
|
}
|
|
|
|
|
loading.value = false
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
getList()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
listMenu({ menuTypeIds: 'M,C' }).then((response) => {
|
|
|
|
@@ -563,5 +561,6 @@ listMenu({ menuTypeIds: 'M,C' }).then((response) => {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 首次列表加载(只加载一层)
|
|
|
|
|
getList()
|
|
|
|
|
// getList(1)
|
|
|
|
|
handleQuery()
|
|
|
|
|
</script>
|
|
|
|
|