|
@@ -1,95 +1,126 @@
|
|
|
<template>
|
|
|
<div class="table-list">
|
|
|
- <div class="filter-container">
|
|
|
- <div class="filter-control">
|
|
|
- <span>菜单状态:</span>
|
|
|
- <el-select
|
|
|
- v-model="listQuery.status"
|
|
|
- placeholder="启用状态"
|
|
|
- clearable
|
|
|
- style="width: 200px"
|
|
|
- class="filter-item"
|
|
|
- @change="getList"
|
|
|
- >
|
|
|
- <el-option label="全部" value="" />
|
|
|
- <el-option label="已启用" :value="0" />
|
|
|
- <el-option label="未启用" :value="1" />
|
|
|
- </el-select>
|
|
|
- </div>
|
|
|
- <div class="filter-control">
|
|
|
- <el-button type="primary" @click="handleAddMenu()">添加菜单</el-button>
|
|
|
+ <div class="app-container">
|
|
|
+ <div class="filter-container">
|
|
|
+ <div class="filter-control">
|
|
|
+ <span>菜单状态:</span>
|
|
|
+ <el-select
|
|
|
+ v-model="listQuery.status"
|
|
|
+ placeholder="启用状态"
|
|
|
+ clearable
|
|
|
+ style="width: 200px"
|
|
|
+ class="filter-item"
|
|
|
+ @change="getList"
|
|
|
+ >
|
|
|
+ <el-option label="全部" value="" />
|
|
|
+ <el-option label="已启用" :value="0" />
|
|
|
+ <el-option label="未启用" :value="1" />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="filter-control">
|
|
|
+ <el-button type="primary" @click="onEditMenu(null, 'add')">添加菜单</el-button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+ <!-- 搜索区域END -->
|
|
|
+ <el-table
|
|
|
+ v-loading="listLoading"
|
|
|
+ class="table-cell"
|
|
|
+ row-key="id"
|
|
|
+ header-row-class-name="tableHeader"
|
|
|
+ border
|
|
|
+ fit
|
|
|
+ lazy
|
|
|
+ :data="list"
|
|
|
+ :load="load"
|
|
|
+ :tree-props="{ hasChildren: 'hasChildren' }"
|
|
|
+ >
|
|
|
+ <el-table-column :index="indexMethod" prop="title" label="序号" type="index" width="60" align="center" />
|
|
|
+ <el-table-column label="菜单名称" prop="title">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="!row.hasChildren" style="margin-right: 23px" />
|
|
|
+ <span>{{ row.title }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="name" label="路由名称" align="center" />
|
|
|
+ <el-table-column label="级别" width="120px" align="center">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ {{ row.level | levelName }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <!-- <el-table-column prop="childCount" label="子菜单数量" align="center" width="100px" /> -->
|
|
|
+ <el-table-column label="图标" align="center" width="80">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <template v-if="row.icon">
|
|
|
+ <i v-if="isElementIcon(row.icon)" :class="row.icon" />
|
|
|
+ <i v-else-if="isOurIcon(row.icon)" :class="row.icon" />
|
|
|
+ <svg-icon v-else :icon-class="row.icon" />
|
|
|
+ </template>
|
|
|
+ <span v-else>无</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column v-if="listQuery.menuType === 2" prop="name" label="功能类别" align="center" width="80px">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span v-if="row.baseFlag === 1">基础</span>
|
|
|
+ <span v-else>订制</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="启用状态" align="center" width="100">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-switch v-model="row.status" :active-value="0" :inactive-value="1" @change="onUpdateMenuStatus(row)" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="sort" label="排序" align="center" width="80">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-input v-model.number="row.sort" @blur="onUpdateMenuSort(row)" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="创建时间" align="center" width="180px">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <span>{{ row.createTime | formatTime }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" align="center" width="260">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-button type="primary" size="mini" @click="onEditMenu(row, 'edit')">编辑</el-button>
|
|
|
+ <el-button type="primary" size="mini" @click="onEditMenu(row, 'child')">添加子菜单</el-button>
|
|
|
+ <el-button type="danger" size="mini" @click="onDeleteMenu(row)">删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <!-- 页码 -->
|
|
|
+ <pagination
|
|
|
+ :total="total"
|
|
|
+ :page.sync="listQuery.pageNum"
|
|
|
+ :limit.sync="listQuery.pageSize"
|
|
|
+ @pagination="getList"
|
|
|
+ />
|
|
|
+ <edit-page
|
|
|
+ :title="editTitle"
|
|
|
+ :show="editDrawer"
|
|
|
+ :menu-type="menuType"
|
|
|
+ :edit-type="editType"
|
|
|
+ :menu-id="currentMenuId"
|
|
|
+ @close="editDrawer = false"
|
|
|
+ @success="onEditSuccess"
|
|
|
+ />
|
|
|
</div>
|
|
|
- <!-- 搜索区域END -->
|
|
|
- <el-table
|
|
|
- v-loading="listLoading"
|
|
|
- :data="list"
|
|
|
- style="width: 100%"
|
|
|
- border
|
|
|
- fit
|
|
|
- header-row-class-name="tableHeader"
|
|
|
- class="table-cell"
|
|
|
- >
|
|
|
- <el-table-column :index="indexMethod" label="序号" type="index" width="80" align="center" />
|
|
|
- <el-table-column prop="title" label="菜单名称" align="center" />
|
|
|
- <el-table-column prop="name" label="路由名称" align="center" />
|
|
|
- <el-table-column label="展示图标" align="center" width="100">
|
|
|
- <template slot-scope="{ row }">
|
|
|
- <i v-if="row.icon" :class="row.icon" />
|
|
|
- <span v-else>无</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column v-if="listQuery.menuType === 2" prop="name" label="会员功能" align="center">
|
|
|
- <template slot-scope="{ row }">
|
|
|
- <span v-if="row.baseFlag === 1">基础功能</span>
|
|
|
- <span v-else>订制功能</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="启用状态" align="center" width="100">
|
|
|
- <template slot-scope="{ row }">
|
|
|
- <el-switch v-model="row.status" :active-value="0" :inactive-value="1" @change="updateMenuStatus(row)" />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column prop="sort" label="排序" align="center" width="100">
|
|
|
- <template slot-scope="{ row }">
|
|
|
- <el-input v-model="row.sort" @change="updateMenuSort(row)" />
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="子菜单管理" align="center" width="240">
|
|
|
- <template slot-scope="{ row }">
|
|
|
- <el-button size="mini" @click="handleSearchChildren(row)">查看子菜单</el-button>
|
|
|
- <el-button size="mini" @click="handleAddMenu(row)">添加子菜单</el-button>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- <el-table-column label="操作" align="center" width="200">
|
|
|
- <template slot-scope="{ row }">
|
|
|
-
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- size="mini"
|
|
|
- @click="handleEditMenu(row)"
|
|
|
- >编辑</el-button>
|
|
|
- <el-button type="danger" size="mini" @click="deleteMenu(row)">删除</el-button>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
- </el-table>
|
|
|
- <!-- 页码 -->
|
|
|
- <pagination
|
|
|
- :total="total"
|
|
|
- :page.sync="listQuery.pageNum"
|
|
|
- :limit.sync="listQuery.pageSize"
|
|
|
- @pagination="getList"
|
|
|
- />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import { fetchMenuList, deleteMenu, updateMenuSelective } from '@/api/system'
|
|
|
-import Pagination from '@/components/Pagination' // secondary package based on el-pagination
|
|
|
+import { fetchMenuList, updateMenuSelective, deleteMenu } from '@/api/system'
|
|
|
+import Pagination from '@/components/Pagination'
|
|
|
+import EditPage from './edit-page.vue'
|
|
|
export default {
|
|
|
name: 'TableList',
|
|
|
components: {
|
|
|
- Pagination
|
|
|
+ Pagination,
|
|
|
+ EditPage
|
|
|
+ },
|
|
|
+ filters: {
|
|
|
+ levelName(level) {
|
|
|
+ return '一二三四五六七八九十'.split('')[level - 1] + '级菜单'
|
|
|
+ }
|
|
|
},
|
|
|
props: {
|
|
|
menuType: {
|
|
@@ -100,6 +131,8 @@ export default {
|
|
|
data() {
|
|
|
return {
|
|
|
listLoading: false,
|
|
|
+ editDrawer: false,
|
|
|
+ editTitle: '',
|
|
|
// 查询参数
|
|
|
listQuery: {
|
|
|
parentId: '',
|
|
@@ -110,111 +143,149 @@ export default {
|
|
|
},
|
|
|
total: 0,
|
|
|
// 菜单列表
|
|
|
- list: []
|
|
|
+ list: [],
|
|
|
+ currentMenuId: 0,
|
|
|
+ currentParentId: 0,
|
|
|
+ editType: 'add'
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
- this.initQuery()
|
|
|
this.getList()
|
|
|
},
|
|
|
methods: {
|
|
|
- // 初始化参数
|
|
|
- initQuery() {
|
|
|
- const { id = '', title = '' } = this.$route.params
|
|
|
- this.listQuery.menuType = this.menuType
|
|
|
- this.parentTitle = title
|
|
|
- this.listQuery.parentId = id
|
|
|
+ // 编辑菜单
|
|
|
+ onEditMenu(row, type) {
|
|
|
+ this.editType = type
|
|
|
+ const titles = {
|
|
|
+ edit: '修改菜单信息',
|
|
|
+ add: '添加菜单',
|
|
|
+ child: '添加子菜单'
|
|
|
+ }
|
|
|
+ this.editTitle = titles[type]
|
|
|
+ if (type === 'edit') {
|
|
|
+ this.currentMenuId = row.id
|
|
|
+ this.currentParentId = row.parentId
|
|
|
+ } else if (type === 'child') {
|
|
|
+ this.currentMenuId = row.id
|
|
|
+ } else {
|
|
|
+ this.currentMenuId = 0
|
|
|
+ }
|
|
|
+ this.editDrawer = true
|
|
|
},
|
|
|
- // 添加菜单
|
|
|
- handleAddMenu(row) {
|
|
|
- if (row) {
|
|
|
- this.$router.push({
|
|
|
- path: '/settings/menus/children/add',
|
|
|
- query: {
|
|
|
- type: 'add',
|
|
|
- parentId: row.id,
|
|
|
- menuType: this.menuType
|
|
|
- }
|
|
|
- })
|
|
|
- } else if (this.listQuery.parentId) {
|
|
|
- this.$router.push({
|
|
|
- path: '/settings/menus/children/add',
|
|
|
- query: {
|
|
|
- type: 'add',
|
|
|
- parentId: this.listQuery.parentId,
|
|
|
- menuType: this.menuType
|
|
|
- }
|
|
|
+
|
|
|
+ // 加载子菜单
|
|
|
+ async load(tree, treeNode, resolve) {
|
|
|
+ try {
|
|
|
+ const res = await fetchMenuList({
|
|
|
+ parentId: tree.id,
|
|
|
+ menuType: this.menuType,
|
|
|
+ status: '',
|
|
|
+ pageSize: 1000,
|
|
|
+ pageNum: 1
|
|
|
})
|
|
|
- } else {
|
|
|
- this.$router.push({
|
|
|
- path: '/settings/menus/add',
|
|
|
- query: {
|
|
|
- type: 'add',
|
|
|
- menuType: this.menuType
|
|
|
- }
|
|
|
+ const list = res.data.list.map((item) => {
|
|
|
+ item.hasChildren = item.childCount > 0
|
|
|
+ item.level = tree.level + 1
|
|
|
+ item.rowId = tree.rowId + '-' + item.id
|
|
|
+ return item
|
|
|
})
|
|
|
+ this.$set(tree, 'chidlren', list) // 菜单列表
|
|
|
+ resolve(list)
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
}
|
|
|
},
|
|
|
- // 查看子菜单
|
|
|
- handleSearchChildren(row) {
|
|
|
- this.listQuery.parentId = row.id
|
|
|
- this.$router.replace(`/settings/menus/children/${this.menuType}/${row.id}/${row.title}`)
|
|
|
- },
|
|
|
- // 修改菜单
|
|
|
- handleEditMenu(row) {
|
|
|
- // $_navigationTo(`/settings/menus/edit?id=${row.id}&type=edit`)
|
|
|
- this.$router.push({
|
|
|
- path: '/settings/menus/edit',
|
|
|
- query: {
|
|
|
- id: row.id,
|
|
|
- type: 'edit',
|
|
|
- menuType: this.menuType
|
|
|
- }
|
|
|
- })
|
|
|
- },
|
|
|
+
|
|
|
// 获取列表
|
|
|
- getList() {
|
|
|
+ async getList() {
|
|
|
+ this.listQuery.menuType = this.menuType
|
|
|
this.listQuery.pageNum = 1
|
|
|
- this.list = []
|
|
|
- this.fetchMenuList()
|
|
|
- },
|
|
|
- // 获取菜单列表
|
|
|
- fetchMenuList() {
|
|
|
- fetchMenuList(this.listQuery).then(res => {
|
|
|
- this.list = [...this.list, ...res.data.list]
|
|
|
+ try {
|
|
|
+ const res = await fetchMenuList(this.listQuery)
|
|
|
+ this.list = res.data.list.map((item) => {
|
|
|
+ item.hasChildren = item.childCount > 0
|
|
|
+ item.level = 1
|
|
|
+ item.rowId = item.id + ''
|
|
|
+ return item
|
|
|
+ })
|
|
|
this.total = res.data.total
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 编辑成功
|
|
|
+ onEditSuccess() {
|
|
|
+ this.$store.dispatch('tagsView/delCachedView', this.$route).then(() => {
|
|
|
+ const { fullPath } = this.$route
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$router.replace({
|
|
|
+ path: '/redirect' + fullPath
|
|
|
+ })
|
|
|
+ })
|
|
|
})
|
|
|
},
|
|
|
+
|
|
|
// 更新状态
|
|
|
- updateMenuStatus(row) {
|
|
|
- updateMenuSelective(row.id, { status: row.status }).then(() => {
|
|
|
+ async onUpdateMenuStatus(row) {
|
|
|
+ try {
|
|
|
+ await updateMenuSelective(row.id, { status: row.status })
|
|
|
this.$message.success('操作成功')
|
|
|
- })
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ this.onEditSuccess()
|
|
|
+ }
|
|
|
},
|
|
|
+
|
|
|
// 更新排序
|
|
|
- updateMenuSort(row) {
|
|
|
- updateMenuSelective(row.id, { sort: row.sort }).then(() => {
|
|
|
+ async onUpdateMenuSort(row) {
|
|
|
+ try {
|
|
|
+ await updateMenuSelective(row.id, { sort: row.sort })
|
|
|
this.$message.success('操作成功')
|
|
|
- this.getList()
|
|
|
- })
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ this.onEditSuccess()
|
|
|
+ }
|
|
|
},
|
|
|
+
|
|
|
// 删除菜单
|
|
|
- deleteMenu(row) {
|
|
|
- this.$confirm('此操作将永久删除该菜单及其子菜单, 是否继续?', '提示', {
|
|
|
- confirmButtonText: '确定',
|
|
|
- cancelButtonText: '取消',
|
|
|
- type: 'warning'
|
|
|
- })
|
|
|
- .then(() => {
|
|
|
- deleteMenu(row.id).then(res => {
|
|
|
- this.$message.success('删除成功')
|
|
|
- this.getList()
|
|
|
- })
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- this.$message.info('已取消删除')
|
|
|
+ async deleteMenu(row) {
|
|
|
+ try {
|
|
|
+ await deleteMenu(row.id)
|
|
|
+ this.$message.success('删除成功')
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error)
|
|
|
+ } finally {
|
|
|
+ this.onEditSuccess()
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ // 删除菜单操作
|
|
|
+ async onDeleteMenu(row) {
|
|
|
+ try {
|
|
|
+ await this.$confirm('此操作将永久删除该菜单及其子菜单, 是否继续?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning'
|
|
|
})
|
|
|
+ this.deleteMenu(row)
|
|
|
+ } catch (error) {
|
|
|
+ this.$message.info('已取消删除')
|
|
|
+ }
|
|
|
},
|
|
|
+
|
|
|
+ // 判断图标类型
|
|
|
+ isElementIcon(value) {
|
|
|
+ return value && value.substr(0, 7) === 'el-icon'
|
|
|
+ },
|
|
|
+
|
|
|
+ // 判断自定义图标
|
|
|
+ isOurIcon(value) {
|
|
|
+ return value && value.startsWith('iconfont')
|
|
|
+ },
|
|
|
+
|
|
|
// 表格索引
|
|
|
indexMethod(index) {
|
|
|
return index + this.listQuery.pageSize * (this.listQuery.pageNum - 1) + 1
|
|
@@ -223,4 +294,3 @@ export default {
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
-<style scoped></style>
|