role.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  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. <template slot="menuLeft">
  21. <el-button type="danger"
  22. size="small"
  23. icon="el-icon-delete"
  24. v-if="permission.role_delete"
  25. plain
  26. @click="handleDelete">删 除
  27. </el-button>
  28. <el-button size="small"
  29. icon="el-icon-setting"
  30. @click="handleRole"
  31. v-if="userInfo.role_name.includes('admin')"
  32. plain>权限设置
  33. </el-button>
  34. </template>
  35. <template slot-scope="{row}" slot="menu">
  36. <el-button
  37. type="text"
  38. icon="el-icon-setting"
  39. size="small"
  40. v-if="userInfo.role_name.includes('admin')"
  41. plain
  42. style="border: 0;background-color: transparent !important;"
  43. @click.stop="handleRowRole(row)"
  44. >权限设置
  45. </el-button>
  46. </template>
  47. </avue-crud>
  48. <el-dialog title="角色权限配置"
  49. append-to-body
  50. :visible.sync="box"
  51. width="345px">
  52. <el-tabs type="border-card">
  53. <el-tab-pane label="菜单权限">
  54. <el-tree :data="menuGrantList"
  55. show-checkbox
  56. node-key="id"
  57. ref="treeMenu"
  58. :default-checked-keys="menuTreeObj"
  59. :props="props">
  60. </el-tree>
  61. </el-tab-pane>
  62. <el-tab-pane label="数据权限">
  63. <el-tree :data="dataScopeGrantList"
  64. show-checkbox
  65. node-key="id"
  66. ref="treeDataScope"
  67. :default-checked-keys="dataScopeTreeObj"
  68. :props="props">
  69. </el-tree>
  70. </el-tab-pane>
  71. <el-tab-pane label="接口权限">
  72. <el-tree :data="apiScopeGrantList"
  73. show-checkbox
  74. node-key="id"
  75. ref="treeApiScope"
  76. :default-checked-keys="apiScopeTreeObj"
  77. :props="props">
  78. </el-tree>
  79. </el-tab-pane>
  80. </el-tabs>
  81. <span slot="footer"
  82. class="dialog-footer">
  83. <el-button @click="box = false">取 消</el-button>
  84. <el-button type="primary"
  85. @click="submit">确 定</el-button>
  86. </span>
  87. </el-dialog>
  88. </basic-container>
  89. </template>
  90. <script>
  91. import {
  92. add,
  93. getList,
  94. getRole,
  95. getRoleAlias,
  96. getRoleTreeById,
  97. grant,
  98. grantTree,
  99. remove,
  100. update
  101. } from "@/api/system/role";
  102. import {mapGetters} from "vuex";
  103. import website from '@/config/website';
  104. import {validatenull} from "@/util/validate";
  105. export default {
  106. data() {
  107. return {
  108. form: {},
  109. box: false,
  110. props: {
  111. label: "title",
  112. value: "key"
  113. },
  114. menuGrantList: [],
  115. dataScopeGrantList: [],
  116. apiScopeGrantList: [],
  117. apiGrantList: [],
  118. menuTreeObj: [],
  119. dataScopeTreeObj: [],
  120. apiScopeTreeObj: [],
  121. selectionList: [],
  122. query: {},
  123. loading: true,
  124. page: {
  125. pageSize: 10,
  126. currentPage: 1,
  127. total: 0
  128. },
  129. option: {
  130. tip: false,
  131. simplePage: true,
  132. searchShow: true,
  133. searchMenuSpan: 6,
  134. tree: true,
  135. border: true,
  136. index: true,
  137. selection: true,
  138. viewBtn: true,
  139. labelWidth: 120,
  140. searchLabelWidth: 120,
  141. menuWidth: 350,
  142. dialogWidth: 600,
  143. dialogClickModal: false,
  144. column: [
  145. {
  146. label: "上级角色",
  147. prop: "parentId",
  148. dicData: [],
  149. type: "tree",
  150. hide: true,
  151. span: 24,
  152. props: {
  153. label: "title"
  154. },
  155. rules: [
  156. {
  157. required: false,
  158. message: "请选择上级角色",
  159. trigger: "click"
  160. }
  161. ]
  162. },
  163. {
  164. label: "角色名称",
  165. prop: "roleName",
  166. search: true,
  167. span: 24,
  168. rules: [
  169. {
  170. required: true,
  171. message: "请输入角色名称",
  172. trigger: "blur"
  173. }
  174. ]
  175. },
  176. {
  177. label: "所属租户",
  178. prop: "tenantId",
  179. type: "tree",
  180. dicUrl: "/api/kd-system/tenant/select",
  181. addDisplay: false,
  182. editDisplay: false,
  183. viewDisplay: website.tenantMode,
  184. span: 24,
  185. props: {
  186. label: "tenantName",
  187. value: "tenantId"
  188. },
  189. hide: !website.tenantMode,
  190. search: website.tenantMode,
  191. rules: [{
  192. required: true,
  193. message: "请输入所属租户",
  194. trigger: "click"
  195. }]
  196. },
  197. {
  198. label: "角色别名",
  199. labelTip: '用于权限校验与标注的属性,可手动录入也可点击现有别名快速录入',
  200. prop: "roleAlias",
  201. search: true,
  202. span: 24,
  203. rules: [
  204. {
  205. required: true,
  206. message: "请输入角色别名",
  207. trigger: "blur"
  208. }
  209. ]
  210. },
  211. {
  212. label: '现有别名',
  213. labelTip: '当前系统已存在的角色别名,点击可快速录入',
  214. prop: 'currentAlias',
  215. type: 'radio',
  216. dicData: [],
  217. props: {
  218. label: 'roleName',
  219. value: 'roleAlias',
  220. },
  221. hide: true,
  222. span: 24,
  223. },
  224. {
  225. label: "角色排序",
  226. prop: "sort",
  227. type: "number",
  228. span: 24,
  229. rules: [
  230. {
  231. required: true,
  232. message: "请输入角色排序",
  233. trigger: "blur"
  234. }
  235. ]
  236. }
  237. ]
  238. },
  239. data: []
  240. };
  241. },
  242. computed: {
  243. ...mapGetters(["userInfo", "permission"]),
  244. permissionList() {
  245. return {
  246. addBtn: this.vaildData(this.permission.role_add, false),
  247. viewBtn: this.vaildData(this.permission.role_view, false),
  248. delBtn: this.vaildData(this.permission.role_delete, false),
  249. editBtn: this.vaildData(this.permission.role_edit, false)
  250. };
  251. },
  252. ids() {
  253. let ids = [];
  254. this.selectionList.forEach(ele => {
  255. ids.push(ele.id);
  256. });
  257. return ids.join(",");
  258. },
  259. idsArray() {
  260. let ids = [];
  261. this.selectionList.forEach(ele => {
  262. ids.push(ele.id);
  263. });
  264. return ids;
  265. }
  266. },
  267. watch: {
  268. 'form.currentAlias'() {
  269. const alias = this.form.currentAlias;
  270. if (!validatenull(alias)) {
  271. this.form.roleAlias = alias;
  272. }
  273. },
  274. },
  275. methods: {
  276. initData(roleId){
  277. getRoleTreeById(roleId).then(res => {
  278. const column = this.findObject(this.option.column, "parentId");
  279. column.dicData = res.data.data;
  280. });
  281. },
  282. submit() {
  283. const menuList = this.$refs.treeMenu.getCheckedKeys();
  284. const dataScopeList = this.$refs.treeDataScope.getCheckedKeys();
  285. const apiScopeList = this.$refs.treeApiScope.getCheckedKeys();
  286. grant(this.idsArray, menuList, dataScopeList, apiScopeList).then(() => {
  287. this.box = false;
  288. this.$message({
  289. type: "success",
  290. message: "操作成功!"
  291. });
  292. this.selectionList = [];
  293. this.onLoad(this.page);
  294. });
  295. },
  296. rowSave(row, done, loading) {
  297. add(row).then(() => {
  298. this.onLoad(this.page);
  299. this.$message({
  300. type: "success",
  301. message: "操作成功!"
  302. });
  303. done();
  304. }, error => {
  305. window.console.log(error);
  306. loading();
  307. });
  308. },
  309. rowUpdate(row, index, done, loading) {
  310. update(row).then(() => {
  311. this.onLoad(this.page);
  312. this.$message({
  313. type: "success",
  314. message: "操作成功!"
  315. });
  316. done();
  317. }, error => {
  318. window.console.log(error);
  319. loading();
  320. });
  321. },
  322. rowDel(row) {
  323. this.$confirm("确定将选择数据删除?", {
  324. confirmButtonText: "确定",
  325. cancelButtonText: "取消",
  326. type: "warning"
  327. })
  328. .then(() => {
  329. return remove(row.id);
  330. })
  331. .then(() => {
  332. this.onLoad(this.page);
  333. this.$message({
  334. type: "success",
  335. message: "操作成功!"
  336. });
  337. });
  338. },
  339. searchReset() {
  340. this.query = {};
  341. this.onLoad(this.page);
  342. },
  343. searchChange(params, done) {
  344. this.query = params;
  345. this.page.currentPage = 1;
  346. this.onLoad(this.page, params);
  347. done();
  348. },
  349. selectionChange(list) {
  350. this.selectionList = list;
  351. },
  352. selectionClear() {
  353. this.selectionList = [];
  354. this.$refs.crud.toggleSelection();
  355. },
  356. beforeOpen(done, type) {
  357. if (["add", "edit"].includes(type)) {
  358. this.initData(this.form.id);
  359. }
  360. getRoleAlias().then(res => {
  361. const column = this.findObject(this.option.column, 'currentAlias');
  362. column.dicData = res.data.data;
  363. });
  364. done();
  365. },
  366. handleRole() {
  367. if (this.selectionList.length !== 1) {
  368. this.$message.warning("只能选择一条数据");
  369. return;
  370. }
  371. this.menuTreeObj = [];
  372. this.dataScopeTreeObj = [];
  373. this.apiScopeTreeObj = [];
  374. grantTree()
  375. .then(res => {
  376. this.menuGrantList = res.data.data.menu;
  377. this.dataScopeGrantList = res.data.data.dataScope;
  378. this.apiScopeGrantList = res.data.data.apiScope;
  379. getRole(this.ids).then(res => {
  380. this.menuTreeObj = res.data.data.menu;
  381. this.dataScopeTreeObj = res.data.data.dataScope;
  382. this.apiScopeTreeObj = res.data.data.apiScope;
  383. this.box = true;
  384. });
  385. });
  386. },
  387. handleRowRole(row) {
  388. this.menuTreeObj = [];
  389. this.dataScopeTreeObj = [];
  390. this.apiScopeTreeObj = [];
  391. grantTree()
  392. .then(res => {
  393. this.menuGrantList = res.data.data.menu;
  394. this.dataScopeGrantList = res.data.data.dataScope;
  395. this.apiScopeGrantList = res.data.data.apiScope;
  396. getRole(row.id).then(res => {
  397. this.menuTreeObj = res.data.data.menu;
  398. this.dataScopeTreeObj = res.data.data.dataScope;
  399. this.apiScopeTreeObj = res.data.data.apiScope;
  400. this.selectionList.push(row);
  401. this.box = true;
  402. });
  403. });
  404. },
  405. handleDelete() {
  406. if (this.selectionList.length === 0) {
  407. this.$message.warning("请选择至少一条数据");
  408. return;
  409. }
  410. this.$confirm("确定将选择数据删除?", {
  411. confirmButtonText: "确定",
  412. cancelButtonText: "取消",
  413. type: "warning"
  414. })
  415. .then(() => {
  416. return remove(this.ids);
  417. })
  418. .then(() => {
  419. this.onLoad(this.page);
  420. this.$message({
  421. type: "success",
  422. message: "操作成功!"
  423. });
  424. this.$refs.crud.toggleSelection();
  425. });
  426. },
  427. currentChange(currentPage) {
  428. this.page.currentPage = currentPage;
  429. },
  430. sizeChange(pageSize) {
  431. this.page.pageSize = pageSize;
  432. },
  433. refreshChange() {
  434. this.onLoad(this.page, this.query);
  435. },
  436. onLoad(page, params = {}) {
  437. this.loading = true;
  438. getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
  439. this.data = res.data.data;
  440. this.loading = false;
  441. this.selectionClear();
  442. });
  443. }
  444. }
  445. };
  446. </script>