This commit is contained in:
张成
2025-10-28 11:24:11 +08:00
parent a8d52f74ad
commit e039ae8c62
39 changed files with 636 additions and 676 deletions

View 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>