datascope.vue 20 KB

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