apiscope.vue 18 KB

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