menu.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. <template>
  2. <basic-container>
  3. <avue-crud :option="option"
  4. :data="data"
  5. ref="crud"
  6. v-model="form"
  7. :permission="permissionList"
  8. :before-open="beforeOpen"
  9. @row-del="rowDel"
  10. @row-update="rowUpdate"
  11. @row-save="rowSave"
  12. @search-change="searchChange"
  13. @search-reset="searchReset"
  14. @selection-change="selectionChange"
  15. @current-change="currentChange"
  16. @size-change="sizeChange"
  17. @on-load="onLoad">
  18. <template slot="menuLeft">
  19. <el-button type="danger"
  20. size="small"
  21. icon="el-icon-delete"
  22. v-if="permission.menu_delete"
  23. plain
  24. @click="handleDelete">删 除
  25. </el-button>
  26. </template>
  27. <template slot-scope="{row}" slot="menu">
  28. <el-button type="text"
  29. icon="el-icon-setting"
  30. size="small"
  31. v-if="permission.menu_data_scope"
  32. plain
  33. class="none-border"
  34. @click.stop="handleDataScope(row)">数据权限
  35. </el-button>
  36. </template>
  37. <template slot-scope="{row}" slot="source">
  38. <div style="text-align:center">
  39. <i :class="row.source"></i>
  40. </div>
  41. </template>
  42. </avue-crud>
  43. <avue-drawer :title="`[${scopeMenuName}] 数据权限配置`" show-close :width="1000" v-model="drawerVisible"
  44. :before-close="handleDrawerClose">
  45. <avue-crud :option="optionScope"
  46. :data="dataScope"
  47. :page="pageScope"
  48. v-model="formScope"
  49. ref="crudScope"
  50. @row-del="rowDelScope"
  51. @row-update="rowUpdateScope"
  52. @row-save="rowSaveScope"
  53. :before-open="beforeOpenScope"
  54. @search-change="searchChangeScope"
  55. @search-reset="searchResetScope"
  56. @selection-change="selectionChangeScope"
  57. @current-change="currentChangeScope"
  58. @size-change="sizeChangeScope"
  59. @on-load="onLoadScope">
  60. <template slot="menuLeft">
  61. <el-button type="danger"
  62. size="small"
  63. icon="el-icon-delete"
  64. plain
  65. @click="handleDeleteScope">删 除
  66. </el-button>
  67. </template>
  68. </avue-crud>
  69. </avue-drawer>
  70. </basic-container>
  71. </template>
  72. <script>
  73. import {add, remove, update, getList, getMenu, addScope, removeScope, updateScope, getListScope, getMenuScope} from "@/api/system/menu";
  74. import {mapGetters} from "vuex";
  75. import iconList from "@/config/iconList";
  76. export default {
  77. data() {
  78. return {
  79. form: {},
  80. selectionList: [],
  81. query: {},
  82. page: {
  83. pageSize: 10,
  84. currentPage: 1,
  85. total: 0
  86. },
  87. drawerVisible: false,
  88. scopeMenuId: 0,
  89. scopeMenuName: "菜单",
  90. menu: true,
  91. option: {
  92. tip: false,
  93. dialogWidth: "60%",
  94. tree: true,
  95. border: true,
  96. index: true,
  97. selection: true,
  98. viewBtn: true,
  99. menuWidth: 250,
  100. column: [
  101. {
  102. label: "菜单名称",
  103. prop: "name",
  104. search: true,
  105. rules: [
  106. {
  107. required: true,
  108. message: "请输入菜单名称",
  109. trigger: "blur"
  110. }
  111. ]
  112. },
  113. {
  114. label: "路由地址",
  115. prop: "path",
  116. rules: [
  117. {
  118. required: true,
  119. message: "请输入路由地址",
  120. trigger: "blur"
  121. }
  122. ]
  123. },
  124. {
  125. label: "上级菜单",
  126. prop: "parentId",
  127. type: "tree",
  128. dicUrl: "/api/blade-system/menu/tree",
  129. hide: true,
  130. props: {
  131. label: "title"
  132. },
  133. rules: [
  134. {
  135. required: false,
  136. message: "请选择上级菜单",
  137. trigger: "click"
  138. }
  139. ]
  140. },
  141. {
  142. label: "菜单图标",
  143. prop: "source",
  144. type: "icon-select",
  145. slot: true,
  146. width: 80,
  147. iconList: iconList,
  148. rules: [
  149. {
  150. required: true,
  151. message: "请输入菜单图标",
  152. trigger: "click"
  153. }
  154. ]
  155. },
  156. {
  157. label: "菜单编号",
  158. prop: "code",
  159. search: true,
  160. rules: [
  161. {
  162. required: true,
  163. message: "请输入菜单编号",
  164. trigger: "blur"
  165. }
  166. ]
  167. },
  168. {
  169. label: "菜单类型",
  170. prop: "category",
  171. type: "radio",
  172. dicData: [
  173. {
  174. label: "菜单",
  175. value: 1
  176. },
  177. {
  178. label: "按钮",
  179. value: 2
  180. }
  181. ],
  182. hide: true,
  183. rules: [
  184. {
  185. required: true,
  186. message: "请选择菜单类型",
  187. trigger: "blur"
  188. }
  189. ]
  190. },
  191. {
  192. label: "菜单别名",
  193. prop: "alias",
  194. rules: [
  195. {
  196. required: true,
  197. message: "请输入菜单别名",
  198. trigger: "blur"
  199. }
  200. ]
  201. },
  202. {
  203. label: "按钮功能",
  204. prop: "action",
  205. type: "radio",
  206. dicData: [
  207. {
  208. label: "工具栏",
  209. value: 0
  210. },
  211. {
  212. label: "操作栏",
  213. value: 1
  214. },
  215. {
  216. label: "工具操作栏",
  217. value: 2
  218. }
  219. ],
  220. hide: true,
  221. rules: [
  222. {
  223. required: true,
  224. message: "请选择按钮功能",
  225. trigger: "blur"
  226. }
  227. ]
  228. },
  229. {
  230. label: "菜单排序",
  231. prop: "sort",
  232. type: "number",
  233. width: 80,
  234. rules: [
  235. {
  236. required: true,
  237. message: "请输入菜单排序",
  238. trigger: "blur"
  239. }
  240. ]
  241. },
  242. {
  243. label: "新窗口",
  244. prop: "isOpen",
  245. type: "radio",
  246. dicData: [
  247. {
  248. label: "否",
  249. value: 0
  250. },
  251. {
  252. label: "是",
  253. value: 1
  254. },
  255. ],
  256. hide: true
  257. },
  258. {
  259. label: "菜单备注",
  260. prop: "remark",
  261. type: "textarea",
  262. span: 24,
  263. minRows: 6,
  264. hide: true
  265. }
  266. ]
  267. },
  268. data: [],
  269. formScope: {},
  270. selectionListScope: [],
  271. pageScope: {
  272. pageSize: 10,
  273. currentPage: 1,
  274. total: 0
  275. },
  276. optionScope: {
  277. tip: false,
  278. border: true,
  279. index: true,
  280. viewBtn: true,
  281. selection: true,
  282. menuWidth: 175,
  283. column: [
  284. {
  285. label: "权限名",
  286. prop: "scopeName",
  287. search: true,
  288. rules: [{
  289. required: true,
  290. message: "请输入数据权限名",
  291. trigger: "blur"
  292. }]
  293. },
  294. {
  295. label: "权限编号",
  296. prop: "resourceCode",
  297. search: true,
  298. width:100,
  299. rules: [{
  300. required: true,
  301. message: "请输入数据权限编号",
  302. trigger: "blur"
  303. }]
  304. },
  305. {
  306. label: "权限字段",
  307. prop: "scopeColumn",
  308. width:130,
  309. rules: [{
  310. required: true,
  311. message: "请输入数据权限编号",
  312. trigger: "blur"
  313. }]
  314. },
  315. {
  316. label: "规则类型",
  317. type: "select",
  318. dicUrl: "/api/blade-system/dict/dictionary?code=scope_type",
  319. props: {
  320. label: "dictValue",
  321. value: "dictKey"
  322. },
  323. width:140,
  324. prop: "scopeType",
  325. rules: [{
  326. required: true,
  327. message: "请输入通知类型",
  328. trigger: "blur"
  329. }]
  330. },
  331. {
  332. label: "权限类名",
  333. prop: "scopeClass",
  334. span: 24,
  335. hide: true,
  336. rules: [{
  337. required: true,
  338. message: "请输入MybatisMapper对应方法的完整类名路径",
  339. trigger: "blur"
  340. }],
  341. },
  342. {
  343. label: "规则值",
  344. prop: "scopeValue",
  345. span: 24,
  346. minRows: 5,
  347. type: "textarea",
  348. hide: true,
  349. },
  350. {
  351. label: "备注",
  352. prop: "remark",
  353. span: 24,
  354. hide: true,
  355. },
  356. ]
  357. },
  358. dataScope: []
  359. };
  360. },
  361. computed: {
  362. ...mapGetters(["permission"]),
  363. permissionList() {
  364. return {
  365. addBtn: this.vaildData(this.permission.menu_add, false),
  366. viewBtn: this.vaildData(this.permission.menu_view, false),
  367. delBtn: this.vaildData(this.permission.menu_delete, false),
  368. editBtn: this.vaildData(this.permission.menu_edit, false)
  369. };
  370. },
  371. ids() {
  372. let ids = [];
  373. this.selectionList.forEach(ele => {
  374. ids.push(ele.id);
  375. });
  376. return ids.join(",");
  377. },
  378. scopeIds() {
  379. let ids = [];
  380. this.selectionListScope.forEach(ele => {
  381. ids.push(ele.id);
  382. });
  383. return ids.join(",");
  384. }
  385. },
  386. methods: {
  387. // 菜单管理模块
  388. rowSave(row, loading, done) {
  389. add(row).then(() => {
  390. loading();
  391. this.onLoad(this.page);
  392. this.$message({
  393. type: "success",
  394. message: "操作成功!"
  395. });
  396. }, error => {
  397. done();
  398. console.log(error);
  399. });
  400. },
  401. rowUpdate(row, index, loading, done) {
  402. update(row).then(() => {
  403. loading();
  404. this.onLoad(this.page);
  405. this.$message({
  406. type: "success",
  407. message: "操作成功!"
  408. });
  409. }, error => {
  410. done();
  411. console.log(error);
  412. });
  413. },
  414. rowDel(row) {
  415. this.$confirm("确定将选择数据删除?", {
  416. confirmButtonText: "确定",
  417. cancelButtonText: "取消",
  418. type: "warning"
  419. })
  420. .then(() => {
  421. return remove(row.id);
  422. })
  423. .then(() => {
  424. this.onLoad(this.page);
  425. this.$message({
  426. type: "success",
  427. message: "操作成功!"
  428. });
  429. });
  430. },
  431. searchReset() {
  432. this.query = {};
  433. this.onLoad(this.page);
  434. },
  435. searchChange(params) {
  436. this.query = params;
  437. this.onLoad(this.page, params);
  438. },
  439. selectionChange(list) {
  440. this.selectionList = list;
  441. },
  442. handleDelete() {
  443. if (this.selectionList.length === 0) {
  444. this.$message.warning("请选择至少一条数据");
  445. return;
  446. }
  447. this.$confirm("确定将选择数据删除?", {
  448. confirmButtonText: "确定",
  449. cancelButtonText: "取消",
  450. type: "warning"
  451. })
  452. .then(() => {
  453. return remove(this.ids);
  454. })
  455. .then(() => {
  456. this.onLoad(this.page);
  457. this.$message({
  458. type: "success",
  459. message: "操作成功!"
  460. });
  461. this.$refs.crud.toggleSelection();
  462. });
  463. },
  464. beforeOpen(done, type) {
  465. if (["edit", "view"].includes(type)) {
  466. getMenu(this.form.id).then(res => {
  467. this.form = res.data.data;
  468. });
  469. }
  470. done();
  471. },
  472. currentChange(currentPage) {
  473. this.page.currentPage = currentPage;
  474. },
  475. sizeChange(pageSize) {
  476. this.page.pageSize = pageSize;
  477. },
  478. onLoad(page, params = {}) {
  479. getList(page.currentPage, page.pageSize, params).then(res => {
  480. this.data = res.data.data;
  481. });
  482. },
  483. // 数据权限模块
  484. handleDataScope(row) {
  485. this.drawerVisible = true;
  486. this.scopeMenuId = row.id;
  487. this.scopeMenuName = row.name;
  488. },
  489. handleDrawerClose(hide) {
  490. hide();
  491. },
  492. rowSaveScope(row, loading, done) {
  493. row = {
  494. ...row,
  495. menuId: this.scopeMenuId,
  496. }
  497. addScope(row).then(() => {
  498. loading();
  499. this.onLoadScope(this.pageScope);
  500. this.$message({
  501. type: "success",
  502. message: "操作成功!"
  503. });
  504. }, error => {
  505. done();
  506. console.log(error);
  507. });
  508. },
  509. rowUpdateScope(row, index, loading, done) {
  510. row = {
  511. ...row,
  512. menuId: this.scopeMenuId,
  513. }
  514. updateScope(row).then(() => {
  515. loading();
  516. this.onLoadScope(this.pageScope);
  517. this.$message({
  518. type: "success",
  519. message: "操作成功!"
  520. });
  521. }, error => {
  522. done();
  523. console.log(error);
  524. });
  525. },
  526. rowDelScope(row) {
  527. this.$confirm("确定将选择数据删除?", {
  528. confirmButtonText: "确定",
  529. cancelButtonText: "取消",
  530. type: "warning"
  531. })
  532. .then(() => {
  533. return removeScope(row.id);
  534. })
  535. .then(() => {
  536. this.onLoadScope(this.pageScope);
  537. this.$message({
  538. type: "success",
  539. message: "操作成功!"
  540. });
  541. });
  542. },
  543. handleDeleteScope() {
  544. if (this.selectionListScope.length === 0) {
  545. this.$message.warning("请选择至少一条数据");
  546. return;
  547. }
  548. this.$confirm("确定将选择数据删除?", {
  549. confirmButtonText: "确定",
  550. cancelButtonText: "取消",
  551. type: "warning"
  552. })
  553. .then(() => {
  554. return removeScope(this.scopeIds);
  555. })
  556. .then(() => {
  557. this.onLoadScope(this.pageScope);
  558. this.$message({
  559. type: "success",
  560. message: "操作成功!"
  561. });
  562. this.$refs.crudScope.toggleSelection();
  563. });
  564. },
  565. beforeOpenScope(done, type) {
  566. if (["edit", "view"].includes(type)) {
  567. getMenuScope(this.formScope.id).then(res => {
  568. this.formScope = res.data.data;
  569. });
  570. }
  571. done();
  572. },
  573. searchResetScope() {
  574. this.onLoadScope(this.pageScope);
  575. },
  576. searchChangeScope(params) {
  577. this.onLoadScope(this.pageScope, params);
  578. },
  579. selectionChangeScope(list) {
  580. this.selectionListScope = list;
  581. },
  582. currentChangeScope(currentPage) {
  583. this.pageScope.currentPage = currentPage;
  584. },
  585. sizeChangeScope(pageSize) {
  586. this.pageScope.pageSize = pageSize;
  587. },
  588. onLoadScope(page, params = {}) {
  589. const values = {
  590. ...params,
  591. menuId: this.scopeMenuId,
  592. }
  593. getListScope(page.currentPage, page.pageSize, Object.assign(values, this.query)).then(res => {
  594. const data = res.data.data;
  595. this.pageScope.total = data.total;
  596. this.dataScope = data.records;
  597. });
  598. },
  599. }
  600. };
  601. </script>
  602. <style>
  603. .none-border {
  604. border: 0;
  605. background-color: transparent !important;
  606. }
  607. </style>