菜单优化
This commit is contained in:
		
							
								
								
									
										248
									
								
								core/apps/AppMenuManager/AppMenuManager.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								core/apps/AppMenuManager/AppMenuManager.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,248 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AppMenuManager"> | ||||||
|  |     <ai-list> | ||||||
|  |       <ai-title slot="title" title="菜单配置" isShowBottomBorder/> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-search-bar> | ||||||
|  |           <template #left> | ||||||
|  |             <el-button type="primary" icon="el-icon-circle-plus" @click="addRootMenu">添加一级目录</el-button> | ||||||
|  |           </template> | ||||||
|  |           <template #right> | ||||||
|  |             <el-button icon="iconfont iconResetting" @click="getData">刷新</el-button> | ||||||
|  |           </template> | ||||||
|  |         </ai-search-bar> | ||||||
|  |         <el-row type="flex" class="headerRow"> | ||||||
|  |           <div class="menuName" v-text="`菜单名称`"/> | ||||||
|  |           <el-row type="flex" align="middle" class="info"> | ||||||
|  |             <div class="style" v-text="`图标`"/> | ||||||
|  |             <div class="type" v-text="`菜单类型`"/> | ||||||
|  |             <div class="component" v-text="`应用模块`"/> | ||||||
|  |             <div class="status" v-text="`是否显示`"/> | ||||||
|  |             <div class="showIndex" v-text="`排序`"/> | ||||||
|  |           </el-row> | ||||||
|  |           <div class="operation" v-text="`操作`"/> | ||||||
|  |         </el-row> | ||||||
|  |         <el-scrollbar> | ||||||
|  |           <el-tree ref="MenuTree" :data="treeData" :props="{children:'subSet'}" highlight-current node-key="id"> | ||||||
|  |             <el-row type="flex" align="middle" slot-scope="{node,data}" class="menuItem"> | ||||||
|  |               <div class="menuName" v-text="data.name"/> | ||||||
|  |               <el-row type="flex" align="middle" class="info"> | ||||||
|  |                 <div class="style" :class="data.style"/> | ||||||
|  |                 <div class="type" v-text="dict.getLabel('menuType',data.type)"/> | ||||||
|  |                 <div class="component" v-text="data.component"/> | ||||||
|  |                 <div class="status" v-text="dict.getLabel('yesOrNo',data.status)"/> | ||||||
|  |                 <div class="showIndex" v-text="data.showIndex"/> | ||||||
|  |               </el-row> | ||||||
|  |               <el-row type="flex" align="middle" class="operation"> | ||||||
|  |                 <div v-if="node.isLeaf" class="opBtn del" v-text="`删除`" @click="handleDelete(data)"/> | ||||||
|  |                 <div v-if="data.type==0" class="opBtn" v-text="`添加下级`" @click="addMenu(data)"/> | ||||||
|  |                 <div class="opBtn" v-text="`编辑`" @click="handleEdit(data)"/> | ||||||
|  |               </el-row> | ||||||
|  |             </el-row> | ||||||
|  |           </el-tree> | ||||||
|  |         </el-scrollbar> | ||||||
|  |       </template> | ||||||
|  |     </ai-list> | ||||||
|  |     <ai-dialog :visible.sync="dialog" title="菜单设置" width="500px" @onConfirm="handleSubmit" | ||||||
|  |                @closed="form={},selected={}"> | ||||||
|  |       <el-form ref="MenuForm" :model="form" size="small" label-width="100px" :rules="rules"> | ||||||
|  |         <el-form-item label="菜单名称" prop="name"> | ||||||
|  |           <el-input v-model="form.name" placeholder="请输入" clearable/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item label="菜单类型" prop="type"> | ||||||
|  |           <ai-select v-model="form.type" clearable :selectList="dict.getDict('menuType')"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <template v-if="form.type==0"> | ||||||
|  |           <el-form-item label="菜单图标" prop="style"> | ||||||
|  |             <el-input v-model="form.style" placeholder="请输入" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |         </template> | ||||||
|  |         <template v-if="form.type==1"> | ||||||
|  |           <el-form-item label="菜单应用" prop="component"> | ||||||
|  |             <el-input v-model="form.component" placeholder="请输入" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |           <el-form-item label="路径(path)" prop="path"> | ||||||
|  |             <el-input v-model="form.path" placeholder="请输入" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |         </template> | ||||||
|  |         <template v-if="form.type==1"> | ||||||
|  |           <el-form-item label="权限码" prop="permission"> | ||||||
|  |             <el-input v-model="form.permission" placeholder="请输入" clearable/> | ||||||
|  |           </el-form-item> | ||||||
|  |         </template> | ||||||
|  |         <el-form-item label="显示菜单" prop="status"> | ||||||
|  |           <ai-select v-model="form.status" clearable :selectList="dict.getDict('yesOrNo')"/> | ||||||
|  |         </el-form-item> | ||||||
|  |         <el-form-item v-if="form.type<2" label="排序" prop="showIndex"> | ||||||
|  |           <el-input v-model="form.showIndex" placeholder="请输入" clearable/> | ||||||
|  |         </el-form-item> | ||||||
|  |       </el-form> | ||||||
|  |     </ai-dialog> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "AppMenuManager", | ||||||
|  |   label: "菜单管理", | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: {default: () => ({})} | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       treeData: [], | ||||||
|  |       dialog: false, | ||||||
|  |       form: {}, | ||||||
|  |       selected: {}, | ||||||
|  |       rules: { | ||||||
|  |         name: [{required: true, message: "请输入 菜单名称"}], | ||||||
|  |         type: [{required: true, message: "请选择 菜单类型"}], | ||||||
|  |         status: [{required: true, message: "请选择 显示菜单"}], | ||||||
|  |         showIndex: [{required: true, message: "请输入 排序"}], | ||||||
|  |         permission: [{required: true, message: "请输入 权限码"}], | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getData() { | ||||||
|  |       this.instance.post("/admin/menu/menuTree").then(res => { | ||||||
|  |         if (res?.data) { | ||||||
|  |           this.treeData = res.data | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleSubmit() { | ||||||
|  |       this.$refs.MenuForm.validate(v => { | ||||||
|  |         if (v) { | ||||||
|  |           this.instance.post("/admin/menu/addOrUpdate", this.form).then(res => { | ||||||
|  |             if (res?.code == 0) { | ||||||
|  |               this.$message.success("提交成功!") | ||||||
|  |               if (!this.form.id) { | ||||||
|  |                 this.getData() | ||||||
|  |               } else this.$refs.MenuTree.append(this.form, this.selected) | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     handleDelete(data) { | ||||||
|  |       let {id} = data | ||||||
|  |       this.$confirm("是否要删除该菜单").then(() => { | ||||||
|  |         this.instance.post("/admin/menu/delete", null, { | ||||||
|  |           params: {id} | ||||||
|  |         }).then(res => { | ||||||
|  |           if (res?.code == 0) { | ||||||
|  |             this.$message.success("删除成功!") | ||||||
|  |             this.$refs.MenuTree.remove(data) | ||||||
|  |           } | ||||||
|  |         }) | ||||||
|  |       }).catch(() => 0) | ||||||
|  |     }, | ||||||
|  |     addRootMenu(row) { | ||||||
|  |       this.dialog = true | ||||||
|  |       this.selected = row | ||||||
|  |     }, | ||||||
|  |     addMenu(row) { | ||||||
|  |       this.dialog = true | ||||||
|  |       this.form = {parentId: row.id} | ||||||
|  |       this.selected = row | ||||||
|  |     }, | ||||||
|  |     handleEdit(row) { | ||||||
|  |       this.dialog = true | ||||||
|  |       this.form = JSON.parse(JSON.stringify(row)) | ||||||
|  |       this.selected = row | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getData() | ||||||
|  |     this.dict.load("yesOrNo", "menuType") | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AppMenuManager { | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   ::v-deep .ai-list__content--right-wrapper { | ||||||
|  |     height: 100%; | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |  | ||||||
|  |     .el-tree { | ||||||
|  |       width: 100%; | ||||||
|  |       height: 100%; | ||||||
|  |       font-size: 14px; | ||||||
|  |  | ||||||
|  |       .menuItem { | ||||||
|  |         flex: 1; | ||||||
|  |         min-width: 0; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .el-tree-node__content { | ||||||
|  |         border-bottom: 1px solid #d0d4dc; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .el-scrollbar { | ||||||
|  |       flex: 1; | ||||||
|  |       min-height: 0; | ||||||
|  |  | ||||||
|  |       .el-scrollbar__wrap { | ||||||
|  |         overflow-x: auto; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     .headerRow { | ||||||
|  |       background: #f3f4f5; | ||||||
|  |       color: #666; | ||||||
|  |       font-weight: bold; | ||||||
|  |       align-items: center; | ||||||
|  |       height: 40px; | ||||||
|  |  | ||||||
|  |       .menuName { | ||||||
|  |         padding-left: 16px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .info { | ||||||
|  |       gap: 16px; | ||||||
|  |       text-align: center; | ||||||
|  |  | ||||||
|  |       .showIndex, .status, .type, .style { | ||||||
|  |         width: 80px; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .component { | ||||||
|  |         width: 300px; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .operation { | ||||||
|  |       width: 200px; | ||||||
|  |       flex-shrink: 0; | ||||||
|  |       justify-content: flex-end; | ||||||
|  |       text-align: center; | ||||||
|  |  | ||||||
|  |       .opBtn { | ||||||
|  |         cursor: pointer; | ||||||
|  |         width: 60px; | ||||||
|  |  | ||||||
|  |         font-size: 14px; | ||||||
|  |         color: #26f; | ||||||
|  |  | ||||||
|  |         &.del { | ||||||
|  |           color: #f46; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .menuName { | ||||||
|  |       flex: 1; | ||||||
|  |       min-width: 0; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -4,5 +4,6 @@ export default [ | |||||||
|   {label: "企业微信配置", name: "AppQyWxConfig"}, |   {label: "企业微信配置", name: "AppQyWxConfig"}, | ||||||
|   {label: "个人中心", name: "AppUserInfo"}, |   {label: "个人中心", name: "AppUserInfo"}, | ||||||
|   {label: "权限管理", name: "AppRightsManager"}, |   {label: "权限管理", name: "AppRightsManager"}, | ||||||
|   {label: "账号角色", name: "AppAccountRole"} |   {label: "账号角色", name: "AppAccountRole"}, | ||||||
|  |   {label: "菜单管理", name: "AppMenuManager"}, | ||||||
| ].map(e => ({...e, component: require(`../core/apps/${e.name}/${e.name}`)?.default})) | ].map(e => ({...e, component: require(`../core/apps/${e.name}/${e.name}`)?.default})) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user