index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. <!--
  2. - Copyright (c) 2018-2025, lengleng All rights reserved.
  3. -
  4. - Redistribution and use in source and binary forms, with or without
  5. - modification, are permitted provided that the following conditions are met:
  6. -
  7. - Redistributions of source code must retain the above copyright notice,
  8. - this list of conditions and the following disclaimer.
  9. - Redistributions in binary form must reproduce the above copyright
  10. - notice, this list of conditions and the following disclaimer in the
  11. - documentation and/or other materials provided with the distribution.
  12. - Neither the name of the pig4cloud.com developer nor the names of its
  13. - contributors may be used to endorse or promote products derived from
  14. - this software without specific prior written permission.
  15. - Author: lengleng (wangiegie@gmail.com)
  16. -->
  17. <template>
  18. <div class="app-container calendar-list-container">
  19. <basic-container>
  20. <div class="filter-container">
  21. <el-button-group>
  22. <el-button type="primary"
  23. v-if="menuManager_btn_add"
  24. icon="plus"
  25. @click="handlerAdd">添加
  26. </el-button>
  27. <el-button type="primary"
  28. v-if="menuManager_btn_edit"
  29. icon="edit"
  30. @click="handlerEdit">编辑
  31. </el-button>
  32. <el-button type="primary"
  33. v-if="menuManager_btn_del"
  34. icon="delete"
  35. @click="handleDelete">删除
  36. </el-button>
  37. </el-button-group>
  38. </div>
  39. <el-row>
  40. <el-col :span="8"
  41. style='margin-top:15px;'>
  42. <el-tree class="filter-tree"
  43. node-key="id"
  44. highlight-current
  45. :data="treeData"
  46. :default-expanded-keys="aExpandedKeys"
  47. :filter-node-method="filterNode"
  48. :props="defaultProps"
  49. @node-click="getNodeData"
  50. @node-expand="nodeExpand"
  51. @node-collapse="nodeCollapse">
  52. </el-tree>
  53. </el-col>
  54. <el-col :span="16"
  55. style='margin-top:15px;'>
  56. <el-card class="box-card">
  57. <el-form :label-position="labelPosition"
  58. label-width="80px"
  59. :model="form"
  60. ref="form">
  61. <el-form-item label="父级节点"
  62. prop="parentId">
  63. <el-input v-model="form.parentId"
  64. :disabled="true"
  65. placeholder="请输入父级节点"></el-input>
  66. </el-form-item>
  67. <el-form-item label="节点ID"
  68. prop="menuId">
  69. <el-input v-model="form.menuId"
  70. :disabled="formEdit || form.menuId"
  71. placeholder="请输入节点ID"></el-input>
  72. </el-form-item>
  73. <el-form-item label="标题"
  74. prop="name">
  75. <el-input v-model="form.name"
  76. :disabled="formEdit"
  77. placeholder="请输入标题"></el-input>
  78. </el-form-item>
  79. <el-form-item label="权限标识"
  80. prop="permission">
  81. <el-input v-model="form.permission"
  82. :disabled="formEdit"
  83. placeholder="请输入权限标识"></el-input>
  84. </el-form-item>
  85. <el-form-item label="图标"
  86. prop="icon">
  87. <avue-crud-icon-select v-model="form.icon"
  88. :iconList="iconList"
  89. :disabled="formEdit"
  90. placeholder="请输入图标"></avue-crud-icon-select>
  91. </el-form-item>
  92. <el-form-item label="类型"
  93. prop="type">
  94. <el-select class="filter-item"
  95. v-model="form.type"
  96. :disabled="formEdit"
  97. placeholder="请输入资源请求类型">
  98. <el-option v-for="item in typeOptions"
  99. :key="item"
  100. :label="item | typeFilter"
  101. :value="item"></el-option>
  102. </el-select>
  103. </el-form-item>
  104. <el-form-item label="排序"
  105. prop="sort">
  106. <el-input type="number"
  107. v-model="form.sort"
  108. :disabled="formEdit"
  109. placeholder="请输入排序"></el-input>
  110. </el-form-item>
  111. <el-form-item label="前端组件"
  112. prop="component">
  113. <el-input v-model="form.component"
  114. :disabled="formEdit"
  115. placeholder="请输入描述"></el-input>
  116. </el-form-item>
  117. <el-form-item label="前端地址"
  118. prop="component">
  119. <el-input v-model="form.path"
  120. :disabled="formEdit"
  121. placeholder="iframe嵌套地址"></el-input>
  122. </el-form-item>
  123. <el-form-item label="路由缓冲"
  124. prop="component">
  125. <el-switch v-model="form.keepAlive"
  126. :disabled="formEdit"
  127. active-color="#13ce66"
  128. inactive-color="#ff4949"
  129. :active-value='"0"'
  130. :inactive-value='"1"'>
  131. </el-switch>
  132. </el-form-item>
  133. <el-form-item v-if="formStatus == 'update'">
  134. <el-button type="primary"
  135. @click="update">更新
  136. </el-button>
  137. <el-button @click="onCancel">取消</el-button>
  138. </el-form-item>
  139. <el-form-item v-if="formStatus == 'create'">
  140. <el-button type="primary"
  141. @click="create">保存
  142. </el-button>
  143. <el-button @click="onCancel">取消</el-button>
  144. </el-form-item>
  145. </el-form>
  146. </el-card>
  147. </el-col>
  148. </el-row>
  149. </basic-container>
  150. </div>
  151. </template>
  152. <script>
  153. import {
  154. addObj,
  155. delObj,
  156. fetchMenuTree,
  157. getObj,
  158. putObj
  159. } from "@/api/admin/menu";
  160. import { mapGetters } from "vuex";
  161. import iconList from "@/const/iconList";
  162. export default {
  163. name: "menu",
  164. data() {
  165. return {
  166. iconList: iconList,
  167. list: null,
  168. total: null,
  169. formEdit: true,
  170. formAdd: true,
  171. formStatus: "",
  172. showElement: false,
  173. typeOptions: ["0", "1"],
  174. methodOptions: ["GET", "POST", "PUT", "DELETE"],
  175. listQuery: {
  176. name: undefined
  177. },
  178. treeData: [],
  179. oExpandedKey: {
  180. // key (from tree id) : expandedOrNot boolean
  181. },
  182. oTreeNodeChildren: {
  183. // id1 : [children] (from tree node id1)
  184. // id2 : [children] (from tree node id2)
  185. },
  186. aExpandedKeys: [],
  187. defaultProps: {
  188. children: "children",
  189. label: "name"
  190. },
  191. labelPosition: "right",
  192. form: {
  193. permission: undefined,
  194. name: undefined,
  195. menuId: undefined,
  196. parentId: undefined,
  197. icon: undefined,
  198. sort: undefined,
  199. component: undefined,
  200. type: undefined,
  201. path: undefined
  202. },
  203. currentId: -1,
  204. menuManager_btn_add: false,
  205. menuManager_btn_edit: false,
  206. menuManager_btn_del: false
  207. };
  208. },
  209. filters: {
  210. typeFilter(type) {
  211. const typeMap = {
  212. 0: "菜单",
  213. 1: "按钮"
  214. };
  215. return typeMap[type];
  216. }
  217. },
  218. created() {
  219. this.getList();
  220. this.menuManager_btn_add = this.permissions["sys_menu_add"];
  221. this.menuManager_btn_edit = this.permissions["sys_menu_edit"];
  222. this.menuManager_btn_del = this.permissions["sys_menu_del"];
  223. },
  224. computed: {
  225. ...mapGetters(["elements", "permissions"])
  226. },
  227. methods: {
  228. getList() {
  229. fetchMenuTree(this.listQuery).then(response => {
  230. this.treeData = response.data.data;
  231. });
  232. },
  233. filterNode(value, data) {
  234. if (!value) return true;
  235. return data.label.indexOf(value) !== -1;
  236. },
  237. nodeExpand(data) {
  238. let aChildren = data.children;
  239. if (aChildren.length > 0) {
  240. this.oExpandedKey[data.id] = true;
  241. this.oTreeNodeChildren[data.id] = aChildren;
  242. }
  243. this.setExpandedKeys();
  244. },
  245. nodeCollapse(data) {
  246. this.oExpandedKey[data.id] = false;
  247. // 如果有子节点
  248. this.treeRecursion(this.oTreeNodeChildren[data.id], oNode => {
  249. this.oExpandedKey[oNode.id] = false;
  250. });
  251. this.setExpandedKeys();
  252. },
  253. setExpandedKeys() {
  254. let oTemp = this.oExpandedKey;
  255. this.aExpandedKeys = [];
  256. for (let sKey in oTemp) {
  257. if (oTemp[sKey]) {
  258. this.aExpandedKeys.push(parseInt(sKey));
  259. }
  260. }
  261. },
  262. treeRecursion(aChildren, fnCallback) {
  263. if (aChildren) {
  264. for (let i = 0; i < aChildren.length; ++i) {
  265. let oNode = aChildren[i];
  266. fnCallback && fnCallback(oNode);
  267. this.treeRecursion(oNode.children, fnCallback);
  268. }
  269. }
  270. },
  271. getNodeData(data) {
  272. if (!this.formEdit) {
  273. this.formStatus = "update";
  274. }
  275. getObj(data.id).then(response => {
  276. this.form = response.data.data;
  277. });
  278. this.currentId = data.id;
  279. this.showElement = true;
  280. },
  281. handlerEdit() {
  282. if (this.form.menuId) {
  283. this.formEdit = false;
  284. this.formStatus = "update";
  285. }
  286. },
  287. handlerAdd() {
  288. this.resetForm();
  289. this.formEdit = false;
  290. this.formStatus = "create";
  291. },
  292. handleDelete() {
  293. this.$confirm("此操作将永久删除, 是否继续?", "提示", {
  294. confirmButtonText: "确定",
  295. cancelButtonText: "取消",
  296. type: "warning"
  297. }).then(() => {
  298. delObj(this.currentId).then(() => {
  299. this.getList();
  300. this.resetForm();
  301. this.onCancel();
  302. this.$notify({
  303. title: "成功",
  304. message: "删除成功",
  305. type: "success",
  306. duration: 2000
  307. });
  308. });
  309. });
  310. },
  311. update() {
  312. putObj(this.form).then(() => {
  313. this.getList();
  314. this.$notify({
  315. title: "成功",
  316. message: "更新成功",
  317. type: "success",
  318. duration: 2000
  319. });
  320. });
  321. },
  322. create() {
  323. addObj(this.form).then(() => {
  324. this.getList();
  325. this.$notify({
  326. title: "成功",
  327. message: "创建成功",
  328. type: "success",
  329. duration: 2000
  330. });
  331. });
  332. },
  333. onCancel() {
  334. this.formEdit = true;
  335. this.formStatus = "";
  336. },
  337. resetForm() {
  338. this.form = {
  339. permission: undefined,
  340. name: undefined,
  341. menuId: undefined,
  342. parentId: this.currentId,
  343. icon: undefined,
  344. sort: undefined,
  345. component: undefined,
  346. type: undefined,
  347. path: undefined
  348. };
  349. }
  350. }
  351. };
  352. </script>