datascope.vue 20 KB

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