1
This commit is contained in:
402
src/views/system/sys_menu.vue
Normal file
402
src/views/system/sys_menu.vue
Normal file
@@ -0,0 +1,402 @@
|
||||
<template>
|
||||
<div class="content-view">
|
||||
<div class="table-head-tool">
|
||||
<Button type="primary" @click="addWarp()">新增</Button>
|
||||
</div>
|
||||
<div class="table-body">
|
||||
<card class="tree-box">
|
||||
<TreeGrid :columns="gridOption.columns" :data="gridOption.data"></TreeGrid>
|
||||
</card>
|
||||
</div>
|
||||
<editModal ref="editModal" :columns="gridOption.editColumns" :rules="gridOption.rules">
|
||||
<div slot="bottom">
|
||||
|
||||
<fieldItem name='类别'>
|
||||
<RadioGroup v-model="editRow.type">
|
||||
<Radio :label="item.key" :key="item.key" v-for="item in typeSource">
|
||||
{{item.value}}
|
||||
</Radio>
|
||||
</RadioGroup>
|
||||
</fieldItem>
|
||||
|
||||
<div v-if="editRow.type==='页面'||editRow.type==='功能'">
|
||||
<fieldItem name='数据模型'>
|
||||
<Select v-model="editRow.model_id">
|
||||
<Option v-for="item in modelRows" :value="item.id" :key="item.id">{{ item.value }}</Option>
|
||||
</Select>
|
||||
</fieldItem>
|
||||
|
||||
<fieldItem name='组件地址'>
|
||||
<Input v-model="editRow.component" placeholder="(模块+路由).vue" />
|
||||
</fieldItem>
|
||||
|
||||
<fieldItem name='api地址'>
|
||||
<Input v-model="editRow.api_path" placeholder="(模型).js" />
|
||||
</fieldItem>
|
||||
</div>
|
||||
|
||||
<fieldItem name='地址' v-if="editRow.type==='外链'">
|
||||
<Input v-model="editRow.component" placeholder="请输入网址" />
|
||||
</fieldItem>
|
||||
|
||||
</div>
|
||||
</editModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import uiTool from '@/utils/uiTool'
|
||||
import menuServer from '@/api/system/menuServer'
|
||||
|
||||
export default {
|
||||
name: 'tree_table_page',
|
||||
data() {
|
||||
let rules = {}
|
||||
rules['name'] = [{ required: true, message: '请填写昵称' }]
|
||||
rules['path'] = [{ required: true, message: '请填写路由' }]
|
||||
rules['icon'] = [{ required: true, message: '请选择图标' }]
|
||||
rules['is_show_menu'] = [{ required: true, message: '请选择是否在菜单' }]
|
||||
rules['is_show'] = [{ required: true, message: '请选择是否启用' }]
|
||||
rules['sort'] = [{ required: true, message: '请填写排序' }]
|
||||
|
||||
const source = [
|
||||
{ key: 0, value: '否' },
|
||||
{ key: 1, value: '是' }
|
||||
]
|
||||
let that = this
|
||||
|
||||
const editColumns = [
|
||||
{ key: 'name', title: '名称' },
|
||||
{
|
||||
key: 'parent_node_ids',
|
||||
title: '父菜单',
|
||||
editRender(h, value) {
|
||||
let val = value || []
|
||||
return h('Cascader', {
|
||||
props: {
|
||||
filterable: true,
|
||||
'change-on-select': true,
|
||||
value: val,
|
||||
data: that.gridOption.menuData
|
||||
},
|
||||
on: {
|
||||
'on-change'(value, selectedData) {
|
||||
that.parent_node_ids = value
|
||||
that.editRow.parent_id = value[value.length - 1]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
{ key: 'path', title: '路由', placeholder: '例:system,user' },
|
||||
{
|
||||
key: 'icon',
|
||||
title: '图标',
|
||||
com: 'SelectIcon',
|
||||
render(h, params) {
|
||||
return h('Icon', { props: { type: params.row.icon, size: '24' } })
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
key: 'is_show_menu',
|
||||
title: '是否显示在菜单',
|
||||
com: 'Radio',
|
||||
source: source,
|
||||
render(h, param) {
|
||||
if (param.row.is_show_menu) {
|
||||
return <span>是</span>
|
||||
} else {
|
||||
return <span>否</span>
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'is_show',
|
||||
title: '是否启用',
|
||||
com: 'Radio',
|
||||
source: source,
|
||||
render(h, param) {
|
||||
if (param.row.is_show) {
|
||||
return <span>是</span>
|
||||
} else {
|
||||
return <span>否</span>
|
||||
}
|
||||
}
|
||||
},
|
||||
{ key: 'sort', title: '排序' }
|
||||
]
|
||||
|
||||
return {
|
||||
parent_node_ids: [],
|
||||
editRow: {
|
||||
type: '',
|
||||
model_id: '',
|
||||
parent_id: '',
|
||||
path: '',
|
||||
component: ''
|
||||
},
|
||||
typeSource: [
|
||||
{ key: '菜单', value: '菜单' },
|
||||
{ key: '页面', value: '页面' },
|
||||
{ key: '功能', value: '功能' },
|
||||
{ key: '外链', value: '外链' }
|
||||
],
|
||||
menuRows: [],
|
||||
modelRows: [{ id: 0, value: '自定义模板', key: 'custom_template' }],
|
||||
gridOption: {
|
||||
rules,
|
||||
editColumns,
|
||||
columns: [
|
||||
{ title: 'id', key: 'id', width: '120', is_show_edit: 0 },
|
||||
...editColumns,
|
||||
{
|
||||
key: 'type',
|
||||
title: '类别',
|
||||
com: 'Radio',
|
||||
source: [
|
||||
{ key: '菜单', value: '菜单' },
|
||||
{ key: '页面', value: '页面' },
|
||||
{ key: '外链', value: '外链' }
|
||||
]
|
||||
},
|
||||
|
||||
{ key: 'component', title: '组件地址' },
|
||||
{ key: 'api_path', title: 'api地址' },
|
||||
{ key: 'model_id', title: '模型id' },
|
||||
{
|
||||
key: 'operat',
|
||||
title: '操作',
|
||||
type: 'template',
|
||||
width: 500,
|
||||
render: (h, params) => {
|
||||
let btns = [
|
||||
{
|
||||
title: '修改',
|
||||
type: 'primary',
|
||||
click: () => {
|
||||
this.editModal(params.row)
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '删除',
|
||||
type: 'primary',
|
||||
click: () => {
|
||||
this.delConfirm(params.row)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
if (params.row.type === '菜单') {
|
||||
btns.push({
|
||||
title: '新增页面',
|
||||
type: 'primary',
|
||||
click: () => {
|
||||
this.addSonWarp(params.row)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (params.row.model_id) {
|
||||
btns.push({
|
||||
title: '自动生成(前端)',
|
||||
type: 'primary',
|
||||
click: () => {
|
||||
this.generate(params.row)
|
||||
}
|
||||
})
|
||||
|
||||
btns.push({
|
||||
title: '自动生成(api)',
|
||||
type: 'primary',
|
||||
click: () => {
|
||||
this.generateModel(params.row)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return uiTool.getBtn(h, btns)
|
||||
}
|
||||
}
|
||||
],
|
||||
data: [],
|
||||
menuData: []
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
this.initCol()
|
||||
},
|
||||
watch: {
|
||||
'editRow.parent_id'() {
|
||||
this.calculate()
|
||||
},
|
||||
'editRow.path'(val) {
|
||||
this.calculate()
|
||||
},
|
||||
'editRow.model_id'(val) {
|
||||
this.calculate()
|
||||
},
|
||||
'editRow.type'(val) {
|
||||
this.calculate()
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async init() {
|
||||
let res = await menuServer.list()
|
||||
let tree = uiTool.transformTree(res.data)
|
||||
this.gridOption.data = this.mapTree(tree)
|
||||
|
||||
let menuRows = res.data.filter((p) => p.type === '菜单')
|
||||
this.menuRows = menuRows
|
||||
let menuTree = uiTool.transformTree(menuRows)
|
||||
this.gridOption.menuData = this.mapTree(menuTree)
|
||||
|
||||
this.$store.dispatch('setAuthorityMenus')
|
||||
},
|
||||
async initCol() {
|
||||
let res = await menuServer.modelAll()
|
||||
|
||||
let data = res.data.map((row) => {
|
||||
let { id, key, name } = row
|
||||
let value = key
|
||||
if (name) {
|
||||
value = value + '-' + name
|
||||
}
|
||||
|
||||
return { id, value, key }
|
||||
})
|
||||
this.modelRows = [{ id: 0, value: '自定义模板', key: 'custom_template' }, ...data] || []
|
||||
},
|
||||
|
||||
calculate() {
|
||||
let modulePath = ''
|
||||
let parent_node_ids = this.parent_node_ids
|
||||
parent_node_ids.forEach((id) => {
|
||||
let menuRow = this.menuRows.find((p) => p.id === id)
|
||||
if (menuRow) {
|
||||
modulePath += menuRow.path + '/'
|
||||
}
|
||||
})
|
||||
|
||||
if (this.editRow.type === '菜单' || this.editRow.type === '外链') {
|
||||
this.editRow.component = ''
|
||||
this.editRow.api_path = ''
|
||||
return
|
||||
}
|
||||
|
||||
if (this.editRow.path) {
|
||||
let path = this.editRow.path.replace(/\//g, '_').replace(/:/g, '')
|
||||
|
||||
this.editRow.component = modulePath + path + '.vue'
|
||||
this.editRow.api_path = modulePath + path + '_server.js'
|
||||
}
|
||||
},
|
||||
mapTree(tree) {
|
||||
let curTree = tree.map((p) => {
|
||||
if (p.children && p.children.length > 0) {
|
||||
p.children = this.mapTree(p.children)
|
||||
}
|
||||
|
||||
return {
|
||||
...p,
|
||||
value: p.id,
|
||||
label: p.name,
|
||||
expand: false,
|
||||
children: p.children
|
||||
}
|
||||
})
|
||||
|
||||
return curTree
|
||||
},
|
||||
editModal(row) {
|
||||
this.parent_node_ids = row.parent_node_ids
|
||||
this.editRow = row
|
||||
this.$refs.editModal.editShow(this.editRow, async (newRow) => {
|
||||
let param = Object.assign({}, this.editRow, newRow)
|
||||
await menuServer.edit(param)
|
||||
this.$Message.success('修改成功!')
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
addWarp() {
|
||||
this.editRow = {
|
||||
type: '菜单',
|
||||
model_id: 0,
|
||||
component: '',
|
||||
parent_id: 0,
|
||||
parent_node_ids: [],
|
||||
path: '',
|
||||
is_show: 1,
|
||||
is_show_menu: 1
|
||||
}
|
||||
this.$refs.editModal.addShow(this.editRow, async (newRow) => {
|
||||
let param = Object.assign({}, newRow)
|
||||
await menuServer.add(param)
|
||||
this.$Message.success('新增成功!')
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
addSonWarp(row) {
|
||||
let { parent_node_ids, id, model_id } = row
|
||||
this.parent_node_ids = parent_node_ids
|
||||
this.editRow = {
|
||||
type: '页面',
|
||||
parent_id: id,
|
||||
model_id,
|
||||
component: '',
|
||||
parent_node_ids,
|
||||
is_show: 1,
|
||||
is_show_menu: 1
|
||||
}
|
||||
this.$refs.editModal.addShow(this.editRow, async (newRow) => {
|
||||
let param = Object.assign({}, newRow)
|
||||
await menuServer.add(param)
|
||||
this.$Message.success('新增成功!')
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
async delConfirm(row) {
|
||||
uiTool.delConfirm(async () => {
|
||||
await menuServer.del(row)
|
||||
this.$Message.success('删除成功!')
|
||||
this.init()
|
||||
})
|
||||
},
|
||||
async generate(row) {
|
||||
uiTool.showConfirm(
|
||||
{
|
||||
content: '你确定生成吗,生成将覆盖原来已存在apiServer和vuePage,请谨慎操作'
|
||||
},
|
||||
async () => {
|
||||
let res = await menuServer.generate(row)
|
||||
this.$Message.success('生成成功!')
|
||||
this.init()
|
||||
}
|
||||
)
|
||||
},
|
||||
async generateModel(row) {
|
||||
uiTool.showConfirm(
|
||||
{
|
||||
content: '你确定生成吗,生成将覆盖原来已存在model和controller,请谨慎操作'
|
||||
},
|
||||
async () => {
|
||||
let res = await menuServer.generateModel(row)
|
||||
this.$Message.success('生成成功!')
|
||||
this.init()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.tree-box {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
max-height: calc(100vh - 200px);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user