配置引导页完成一部分
This commit is contained in:
		| @@ -1,175 +1,29 @@ | |||||||
| <template> | <template> | ||||||
|   <section class="AppMenuManager"> |   <section class="AppMenuManager"> | ||||||
|     <ai-list> |     <component :is="currentPage" v-bind="$props"/> | ||||||
|       <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-input size="small" v-model="search" clearable @change="$refs.MenuTree.filter(search)" |  | ||||||
|                       placeholder="菜单名称"/> |  | ||||||
|             <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" |  | ||||||
|                    :filter-node-method="handleSearch"> |  | ||||||
|             <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<2" 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==2"> |  | ||||||
|           <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> |   </section> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
| <script> | <script> | ||||||
|  | import List from "./list"; | ||||||
|  | import IntroPage from "./introPage"; | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   name: "AppMenuManager", |   name: "AppMenuManager", | ||||||
|  |   components: {IntroPage, List}, | ||||||
|   label: "菜单管理", |   label: "菜单管理", | ||||||
|   props: { |   props: { | ||||||
|     instance: Function, |     instance: Function, | ||||||
|     dict: {default: () => ({})} |     dict: {default: () => ({})} | ||||||
|   }, |   }, | ||||||
|   data() { |   computed: { | ||||||
|     return { |     currentPage() { | ||||||
|       treeData: [], |       const {hash} = this.$route | ||||||
|       dialog: false, |       return hash == "#intro" ? IntroPage : List | ||||||
|       form: {}, |  | ||||||
|       selected: {}, |  | ||||||
|       rules: { |  | ||||||
|         name: [{required: true, message: "请输入 菜单名称"}], |  | ||||||
|         type: [{required: true, message: "请选择 菜单类型"}], |  | ||||||
|         status: [{required: true, message: "请选择 显示菜单"}], |  | ||||||
|         showIndex: [{required: true, message: "请输入 排序"}], |  | ||||||
|         permission: [{required: true, message: "请输入 权限码"}], |  | ||||||
|       }, |  | ||||||
|       search: "" |  | ||||||
|     } |  | ||||||
|   }, |  | ||||||
|   methods: { |  | ||||||
|     getData() { |  | ||||||
|       return 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("提交成功!") |  | ||||||
|               this.dialog = false |  | ||||||
|               if (!!this.form.id) { |  | ||||||
|                 let node = this.$refs.MenuTree.getNode(this.form) |  | ||||||
|                 node.data = this.form |  | ||||||
|               } else if (!!this.form.parentId) { |  | ||||||
|                 this.$refs.MenuTree.append(this.form, this.selected) |  | ||||||
|               } else this.getData() |  | ||||||
|             } |  | ||||||
|           }) |  | ||||||
|         } |  | ||||||
|       }) |  | ||||||
|     }, |  | ||||||
|     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.dialog = false |  | ||||||
|             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 |  | ||||||
|     }, |  | ||||||
|     handleSearch(value, data) { |  | ||||||
|       if (!value) return true; |  | ||||||
|       return data.name.indexOf(value) !== -1; |  | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   created() { |   created() { | ||||||
|     this.getData() |     this.dict.load("menuType") | ||||||
|     this.dict.load("yesOrNo", "menuType") |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
| @@ -177,85 +31,5 @@ export default { | |||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .AppMenuManager { | .AppMenuManager { | ||||||
|   height: 100%; |   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> | </style> | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								core/apps/AppMenuManager/introPage.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								core/apps/AppMenuManager/introPage.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="introPage"> | ||||||
|  |     <ai-detail list> | ||||||
|  |       <ai-title slot="title" title="引导页配置" isShowBottomBorder> | ||||||
|  |         <template #rightBtn> | ||||||
|  |           <el-row type="flex"> | ||||||
|  |             <component-lib @select="handleAddComp"/> | ||||||
|  |             <el-button type="text" @click="submit">保存</el-button> | ||||||
|  |             <el-button type="text" @click="">取消</el-button> | ||||||
|  |           </el-row> | ||||||
|  |         </template> | ||||||
|  |       </ai-title> | ||||||
|  |       <template #content> | ||||||
|  |         <ai-drag v-for="comp in configs" :key="comp.value" :w="comp.width" :h="comp.height" parent> | ||||||
|  |           <comp-render :ops="comp"/> | ||||||
|  |         </ai-drag> | ||||||
|  |         <div v-if="!hasConfigs" class="empty">编辑区域</div> | ||||||
|  |       </template> | ||||||
|  |     </ai-detail> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import AiDrag from "../../components/AiDrag"; | ||||||
|  | import ComponentLib from "./tools/componentLib"; | ||||||
|  | import AiEditBtn from "../../components/AiEditBtn"; | ||||||
|  | import CompRender from "./tools/compRender"; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "introPage", | ||||||
|  |   components: {CompRender, AiEditBtn, ComponentLib, AiDrag}, | ||||||
|  |   props: { | ||||||
|  |     instance: Function, | ||||||
|  |     dict: {default: () => ({})} | ||||||
|  |   }, | ||||||
|  |   computed: { | ||||||
|  |     hasConfigs: v => v.configs?.length > 0 | ||||||
|  |   }, | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       form: {}, | ||||||
|  |       configs: [] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     handleAddComp(comp) { | ||||||
|  |       console.log(comp) | ||||||
|  |       this.configs.push({...comp}) | ||||||
|  |     }, | ||||||
|  |     submit() { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .introPage { | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   .empty { | ||||||
|  |     width: 100%; | ||||||
|  |     min-height: calc(100vh - 180px); | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: center; | ||||||
|  |     align-items: center; | ||||||
|  |     font-size: 48px; | ||||||
|  |     color: #999; | ||||||
|  |     border: 1px dashed #ddd; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ::v-deep.ai-detail__content--wrapper { | ||||||
|  |     min-height: 100%; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										265
									
								
								core/apps/AppMenuManager/list.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										265
									
								
								core/apps/AppMenuManager/list.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,265 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="list"> | ||||||
|  |     <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-input size="small" v-model="search" clearable @change="$refs.MenuTree.filter(search)" | ||||||
|  |                       placeholder="菜单名称"/> | ||||||
|  |             <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" | ||||||
|  |                    :filter-node-method="handleSearch"> | ||||||
|  |             <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.component&&data.type==1" class="opBtn" v-text="`引导页`" @click="$router.push({hash:'#intro',query:{id:data.id}})"/> | ||||||
|  |                 <div v-if="data.type<2" 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==2"> | ||||||
|  |           <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: "list", | ||||||
|  |   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: "请输入 权限码"}], | ||||||
|  |       }, | ||||||
|  |       search: "" | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     getData() { | ||||||
|  |       return 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("提交成功!") | ||||||
|  |               this.dialog = false | ||||||
|  |               if (!!this.form.id) { | ||||||
|  |                 let node = this.$refs.MenuTree.getNode(this.form) | ||||||
|  |                 node.data = this.form | ||||||
|  |               } else if (!!this.form.parentId) { | ||||||
|  |                 this.$refs.MenuTree.append(this.form, this.selected) | ||||||
|  |               } else this.getData() | ||||||
|  |             } | ||||||
|  |           }) | ||||||
|  |         } | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     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.dialog = false | ||||||
|  |             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 | ||||||
|  |     }, | ||||||
|  |     handleSearch(value, data) { | ||||||
|  |       if (!value) return true; | ||||||
|  |       return data.name.indexOf(value) !== -1; | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |     this.getData() | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .list { | ||||||
|  |   height: 100%; | ||||||
|  |  | ||||||
|  |   ::v-deep .ai-list__content--right-wrapper { | ||||||
|  |     height: calc(100% - 10px); | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |  | ||||||
|  |     .el-tree { | ||||||
|  |       width: 100%; | ||||||
|  |       height: 100%; | ||||||
|  |       font-size: 14px; | ||||||
|  |  | ||||||
|  |       .menuItem { | ||||||
|  |         flex: 1; | ||||||
|  |         min-width: 0; | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .el-tree-node:nth-of-type(2n) { | ||||||
|  |         background: rgba(#26f, .05); | ||||||
|  |       } | ||||||
|  |  | ||||||
|  |       .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: 300px; | ||||||
|  |       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> | ||||||
							
								
								
									
										22
									
								
								core/apps/AppMenuManager/tools/compRender.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								core/apps/AppMenuManager/tools/compRender.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="compRender"> | ||||||
|  |  | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "compRender", | ||||||
|  |   data() { | ||||||
|  |     return {} | ||||||
|  |   }, | ||||||
|  |   methods: {}, | ||||||
|  |   created() { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .compRender { | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										67
									
								
								core/apps/AppMenuManager/tools/componentLib.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								core/apps/AppMenuManager/tools/componentLib.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="componentLib"> | ||||||
|  |     <el-button type="text" @click="drawer=true">组件库</el-button> | ||||||
|  |     <el-drawer title="组件库" :visible.sync="drawer" direction="ltr" :modal="false" size="100%"> | ||||||
|  |       <el-row class="item" type="flex" align="middle" v-for="item in list" :key="item.value" @click.native="handleClick"> | ||||||
|  |         <i class="icon" :class="item.icon"/> | ||||||
|  |         <div class="fill mar-l8" v-text="item.label"/> | ||||||
|  |       </el-row> | ||||||
|  |     </el-drawer> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "componentLib", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       drawer: true, | ||||||
|  |       list: [ | ||||||
|  |         {value: 'text', icon: 'iconfont iconrich_text', label: "文字组件", width: 300, height: 32}, | ||||||
|  |         {value: 'image', icon: 'el-icon-picture', label: "图片组件", width: 300, height: 300}, | ||||||
|  |         {value: 'startBtn', icon: 'el-icon-video-play', label: "开始使用", width: 80, height: 32}, | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     handleClick(item) { | ||||||
|  |       this.$emit('select', item) | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   created() { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .componentLib { | ||||||
|  |   .mar-l8 { | ||||||
|  |     margin-left: 8px; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   .item { | ||||||
|  |     font-size: 16px; | ||||||
|  |     margin: 8px; | ||||||
|  |     padding: 4px; | ||||||
|  |     border: 1px dashed #ddd; | ||||||
|  |     cursor: pointer; | ||||||
|  |  | ||||||
|  |     &:hover { | ||||||
|  |       opacity: .8; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     .icon { | ||||||
|  |       font-size: 20px; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   ::v-deep.el-drawer__wrapper { | ||||||
|  |     position: fixed !important; | ||||||
|  |     top: 96px; | ||||||
|  |     bottom: 0; | ||||||
|  |     left: 0; | ||||||
|  |     width: 200px; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										22
									
								
								core/apps/AppMenuManager/tools/fieldPane.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								core/apps/AppMenuManager/tools/fieldPane.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="fieldPane"> | ||||||
|  |     <el-drawer></el-drawer> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "fieldPane", | ||||||
|  |   data() { | ||||||
|  |     return {} | ||||||
|  |   }, | ||||||
|  |   methods: {}, | ||||||
|  |   created() { | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .fieldPane { | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										35
									
								
								core/components/AiDrag.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								core/components/AiDrag.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AiDrag"> | ||||||
|  |     <vue-draggable-resizable v-bind="$attrs"> | ||||||
|  |       <slot/> | ||||||
|  |     </vue-draggable-resizable> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | import 'vue-draggable-resizable/dist/VueDraggableResizable.css' | ||||||
|  | import VueDraggableResizable from 'vue-draggable-resizable' | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |   name: "AiDrag", | ||||||
|  |   components: {VueDraggableResizable}, | ||||||
|  |   props: { | ||||||
|  |     type: {default: "show"} //show:只拖拽 | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AiDrag { | ||||||
|  |   position: absolute; | ||||||
|  |   top: 0; | ||||||
|  |   bottom: 0; | ||||||
|  |   left: 0; | ||||||
|  |   right: 0; | ||||||
|  |   pointer-events: none; | ||||||
|  |  | ||||||
|  |   ::v-deep.vdr { | ||||||
|  |     pointer-events: auto; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
							
								
								
									
										31
									
								
								core/components/AiEditBtn.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								core/components/AiEditBtn.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | |||||||
|  | <template> | ||||||
|  |   <section class="AiEditBtn"> | ||||||
|  |     <el-button v-if="!edit" type="text" @click="handleOper('edit')">编辑</el-button> | ||||||
|  |     <template v-else> | ||||||
|  |       <el-button type="text" @click="handleOper('submit')">保存</el-button> | ||||||
|  |       <el-button type="text" @click="handleOper('cancel')">取消</el-button> | ||||||
|  |     </template> | ||||||
|  |   </section> | ||||||
|  | </template> | ||||||
|  |  | ||||||
|  | <script> | ||||||
|  | export default { | ||||||
|  |   name: "AiEditBtn", | ||||||
|  |   data() { | ||||||
|  |     return { | ||||||
|  |       edit: false | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     handleOper(event) { | ||||||
|  |       this.edit = !this.edit | ||||||
|  |       this.$emit(event) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  |  | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .AiEditBtn { | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @@ -7,6 +7,6 @@ | |||||||
|     "dist" |     "dist" | ||||||
|   ], |   ], | ||||||
|   "publishConfig": { |   "publishConfig": { | ||||||
|     "registry": "http://192.168.1.87:4873/" |     "registry": "http://cli.sinoecare.net" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user