xm
2024-06-14 722af26bc6fec32bb289b1df51a9016a4935610f
提交 | 用户 | 时间
722af2 1 <template>
X 2   <div class="app-container">
3     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch">
4       <el-form-item label="角色名称" prop="roleName">
5         <el-input
6           v-model="queryParams.roleName"
7           placeholder="请输入角色名称"
8           clearable
9           style="width: 240px"
10           @keyup.enter.native="handleQuery"
11         />
12       </el-form-item>
13       <el-form-item label="权限字符" prop="roleKey">
14         <el-input
15           v-model="queryParams.roleKey"
16           placeholder="请输入权限字符"
17           clearable
18           style="width: 240px"
19           @keyup.enter.native="handleQuery"
20         />
21       </el-form-item>
22       <el-form-item label="状态" prop="status">
23         <el-select
24           v-model="queryParams.status"
25           placeholder="角色状态"
26           clearable
27           style="width: 240px"
28         >
29           <el-option
30             v-for="dict in dict.type.sys_normal_disable"
31             :key="dict.value"
32             :label="dict.label"
33             :value="dict.value"
34           />
35         </el-select>
36       </el-form-item>
37       <el-form-item label="创建时间">
38         <el-date-picker
39           v-model="dateRange"
40           style="width: 240px"
41           value-format="yyyy-MM-dd HH:mm:ss"
42           type="daterange"
43           range-separator="-"
44           start-placeholder="开始日期"
45           end-placeholder="结束日期"
46           :default-time="['00:00:00', '23:59:59']"
47         ></el-date-picker>
48       </el-form-item>
49       <el-form-item>
50         <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
51         <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
52       </el-form-item>
53     </el-form>
54
55     <el-row :gutter="10" class="mb8">
56       <el-col :span="1.5">
57         <el-button
58           type="primary"
59           plain
60           icon="el-icon-plus"
61           size="mini"
62           @click="handleAdd"
63           v-hasPermi="['system:role:add']"
64         >新增</el-button>
65       </el-col>
66       <el-col :span="1.5">
67         <el-button
68           type="success"
69           plain
70           icon="el-icon-edit"
71           size="mini"
72           :disabled="single"
73           @click="handleUpdate"
74           v-hasPermi="['system:role:edit']"
75         >修改</el-button>
76       </el-col>
77       <el-col :span="1.5">
78         <el-button
79           type="danger"
80           plain
81           icon="el-icon-delete"
82           size="mini"
83           :disabled="multiple"
84           @click="handleDelete"
85           v-hasPermi="['system:role:remove']"
86         >删除</el-button>
87       </el-col>
88       <el-col :span="1.5">
89         <el-button
90           type="warning"
91           plain
92           icon="el-icon-download"
93           size="mini"
94           @click="handleExport"
95           v-hasPermi="['system:role:export']"
96         >导出</el-button>
97       </el-col>
98       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
99     </el-row>
100
101     <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
102       <el-table-column type="selection" width="55" align="center" />
103       <el-table-column label="角色编号" prop="roleId" width="120" />
104       <el-table-column label="角色名称" prop="roleName" :show-overflow-tooltip="true" width="150" />
105       <el-table-column label="权限字符" prop="roleKey" :show-overflow-tooltip="true" width="150" />
106       <el-table-column label="显示顺序" prop="roleSort" width="100" />
107       <el-table-column label="状态" align="center" width="100">
108         <template slot-scope="scope">
109           <el-switch
110             v-model="scope.row.status"
111             active-value="0"
112             inactive-value="1"
113             @change="handleStatusChange(scope.row)"
114           ></el-switch>
115         </template>
116       </el-table-column>
117       <el-table-column label="创建时间" align="center" prop="createTime" width="180">
118         <template slot-scope="scope">
119           <span>{{ parseTime(scope.row.createTime) }}</span>
120         </template>
121       </el-table-column>
122       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
123         <template slot-scope="scope" v-if="scope.row.roleId !== 1">
124           <el-button
125             size="mini"
126             type="text"
127             icon="el-icon-edit"
128             @click="handleUpdate(scope.row)"
129             v-hasPermi="['system:role:edit']"
130           >修改</el-button>
131           <el-button
132             size="mini"
133             type="text"
134             icon="el-icon-delete"
135             @click="handleDelete(scope.row)"
136             v-hasPermi="['system:role:remove']"
137           >删除</el-button>
138           <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
139             <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
140             <el-dropdown-menu slot="dropdown">
141               <el-dropdown-item command="handleDataScope" icon="el-icon-circle-check"
142                 v-hasPermi="['system:role:edit']">数据权限</el-dropdown-item>
143               <el-dropdown-item command="handleAuthUser" icon="el-icon-user"
144                 v-hasPermi="['system:role:edit']">分配用户</el-dropdown-item>
145             </el-dropdown-menu>
146           </el-dropdown>
147         </template>
148       </el-table-column>
149     </el-table>
150
151     <pagination
152       v-show="total>0"
153       :total="total"
154       :page.sync="queryParams.pageNum"
155       :limit.sync="queryParams.pageSize"
156       @pagination="getList"
157     />
158
159     <!-- 添加或修改角色配置对话框 -->
160     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
161       <el-form ref="form" :model="form" :rules="rules" label-width="100px">
162         <el-form-item label="角色名称" prop="roleName">
163           <el-input v-model="form.roleName" placeholder="请输入角色名称" />
164         </el-form-item>
165         <el-form-item prop="roleKey">
166           <span slot="label">
167             <el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasRole('admin')`)" placement="top">
168               <i class="el-icon-question"></i>
169             </el-tooltip>
170             权限字符
171           </span>
172           <el-input v-model="form.roleKey" placeholder="请输入权限字符" />
173         </el-form-item>
174         <el-form-item label="角色顺序" prop="roleSort">
175           <el-input-number v-model="form.roleSort" controls-position="right" :min="0" />
176         </el-form-item>
177         <el-form-item label="状态">
178           <el-radio-group v-model="form.status">
179             <el-radio
180               v-for="dict in dict.type.sys_normal_disable"
181               :key="dict.value"
182               :label="dict.value"
183             >{{dict.label}}</el-radio>
184           </el-radio-group>
185         </el-form-item>
186         <el-form-item label="菜单权限">
187           <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand($event, 'menu')">展开/折叠</el-checkbox>
188           <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll($event, 'menu')">全选/全不选</el-checkbox>
189           <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect($event, 'menu')">父子联动</el-checkbox>
190           <el-tree
191             class="tree-border"
192             :data="menuOptions"
193             show-checkbox
194             ref="menu"
195             node-key="id"
196             :check-strictly="!form.menuCheckStrictly"
197             empty-text="加载中,请稍候"
198             :props="defaultProps"
199           ></el-tree>
200         </el-form-item>
201         <el-form-item label="备注">
202           <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
203         </el-form-item>
204       </el-form>
205       <div slot="footer" class="dialog-footer">
206         <el-button type="primary" @click="submitForm">确 定</el-button>
207         <el-button @click="cancel">取 消</el-button>
208       </div>
209     </el-dialog>
210
211     <!-- 分配角色数据权限对话框 -->
212     <el-dialog :title="title" :visible.sync="openDataScope" width="500px" append-to-body>
213       <el-form :model="form" label-width="80px">
214         <el-form-item label="角色名称">
215           <el-input v-model="form.roleName" :disabled="true" />
216         </el-form-item>
217         <el-form-item label="权限字符">
218           <el-input v-model="form.roleKey" :disabled="true" />
219         </el-form-item>
220         <el-form-item label="权限范围">
221           <el-select v-model="form.dataScope" @change="dataScopeSelectChange">
222             <el-option
223               v-for="item in dataScopeOptions"
224               :key="item.value"
225               :label="item.label"
226               :value="item.value"
227             ></el-option>
228           </el-select>
229         </el-form-item>
230         <el-form-item label="数据权限" v-show="form.dataScope == 2">
231           <el-checkbox v-model="deptExpand" @change="handleCheckedTreeExpand($event, 'dept')">展开/折叠</el-checkbox>
232           <el-checkbox v-model="deptNodeAll" @change="handleCheckedTreeNodeAll($event, 'dept')">全选/全不选</el-checkbox>
233           <el-checkbox v-model="form.deptCheckStrictly" @change="handleCheckedTreeConnect($event, 'dept')">父子联动</el-checkbox>
234           <el-tree
235             class="tree-border"
236             :data="deptOptions"
237             show-checkbox
238             default-expand-all
239             ref="dept"
240             node-key="id"
241             :check-strictly="!form.deptCheckStrictly"
242             empty-text="加载中,请稍候"
243             :props="defaultProps"
244           ></el-tree>
245         </el-form-item>
246       </el-form>
247       <div slot="footer" class="dialog-footer">
248         <el-button type="primary" @click="submitDataScope">确 定</el-button>
249         <el-button @click="cancelDataScope">取 消</el-button>
250       </div>
251     </el-dialog>
252   </div>
253 </template>
254
255 <script>
256 import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus, deptTreeSelect } from "@/api/system/role";
257 import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
258
259 export default {
260   name: "Role",
261   dicts: ['sys_normal_disable'],
262   data() {
263     return {
264       // 遮罩层
265       loading: true,
266       // 选中数组
267       ids: [],
268       // 非单个禁用
269       single: true,
270       // 非多个禁用
271       multiple: true,
272       // 显示搜索条件
273       showSearch: true,
274       // 总条数
275       total: 0,
276       // 角色表格数据
277       roleList: [],
278       // 弹出层标题
279       title: "",
280       // 是否显示弹出层
281       open: false,
282       // 是否显示弹出层(数据权限)
283       openDataScope: false,
284       menuExpand: false,
285       menuNodeAll: false,
286       deptExpand: true,
287       deptNodeAll: false,
288       // 日期范围
289       dateRange: [],
290       // 数据范围选项
291       dataScopeOptions: [
292         {
293           value: "1",
294           label: "全部数据权限"
295         },
296         {
297           value: "2",
298           label: "自定数据权限"
299         },
300         {
301           value: "3",
302           label: "本部门数据权限"
303         },
304         {
305           value: "4",
306           label: "本部门及以下数据权限"
307         },
308         {
309           value: "5",
310           label: "仅本人数据权限"
311         }
312       ],
313       // 菜单列表
314       menuOptions: [],
315       // 部门列表
316       deptOptions: [],
317       // 查询参数
318       queryParams: {
319         pageNum: 1,
320         pageSize: 10,
321         roleName: undefined,
322         roleKey: undefined,
323         status: undefined
324       },
325       // 表单参数
326       form: {},
327       defaultProps: {
328         children: "children",
329         label: "label"
330       },
331       // 表单校验
332       rules: {
333         roleName: [
334           { required: true, message: "角色名称不能为空", trigger: "blur" }
335         ],
336         roleKey: [
337           { required: true, message: "权限字符不能为空", trigger: "blur" }
338         ],
339         roleSort: [
340           { required: true, message: "角色顺序不能为空", trigger: "blur" }
341         ]
342       }
343     };
344   },
345   created() {
346     this.getList();
347   },
348   methods: {
349     /** 查询角色列表 */
350     getList() {
351       this.loading = true;
352       listRole(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
353           this.roleList = response.rows;
354           this.total = response.total;
355           this.loading = false;
356         }
357       );
358     },
359     /** 查询菜单树结构 */
360     getMenuTreeselect() {
361       menuTreeselect().then(response => {
362         this.menuOptions = response.data;
363       });
364     },
365     // 所有菜单节点数据
366     getMenuAllCheckedKeys() {
367       // 目前被选中的菜单节点
368       let checkedKeys = this.$refs.menu.getCheckedKeys();
369       // 半选中的菜单节点
370       let halfCheckedKeys = this.$refs.menu.getHalfCheckedKeys();
371       checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
372       return checkedKeys;
373     },
374     // 所有部门节点数据
375     getDeptAllCheckedKeys() {
376       // 目前被选中的部门节点
377       let checkedKeys = this.$refs.dept.getCheckedKeys();
378       // 半选中的部门节点
379       let halfCheckedKeys = this.$refs.dept.getHalfCheckedKeys();
380       checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
381       return checkedKeys;
382     },
383     /** 根据角色ID查询菜单树结构 */
384     getRoleMenuTreeselect(roleId) {
385       return roleMenuTreeselect(roleId).then(response => {
386         this.menuOptions = response.data.menus;
387         return response;
388       });
389     },
390     /** 根据角色ID查询部门树结构 */
391     getDeptTree(roleId) {
392       return deptTreeSelect(roleId).then(response => {
393         this.deptOptions = response.data.depts;
394         return response;
395       });
396     },
397     // 角色状态修改
398     handleStatusChange(row) {
399       let text = row.status === "0" ? "启用" : "停用";
400       this.$modal.confirm('确认要"' + text + '""' + row.roleName + '"角色吗?').then(function() {
401         return changeRoleStatus(row.roleId, row.status);
402       }).then(() => {
403         this.$modal.msgSuccess(text + "成功");
404       }).catch(function() {
405         row.status = row.status === "0" ? "1" : "0";
406       });
407     },
408     // 取消按钮
409     cancel() {
410       this.open = false;
411       this.reset();
412     },
413     // 取消按钮(数据权限)
414     cancelDataScope() {
415       this.openDataScope = false;
416       this.reset();
417     },
418     // 表单重置
419     reset() {
420       if (this.$refs.menu != undefined) {
421         this.$refs.menu.setCheckedKeys([]);
422       }
423       this.menuExpand = false,
424       this.menuNodeAll = false,
425       this.deptExpand = true,
426       this.deptNodeAll = false,
427       this.form = {
428         roleId: undefined,
429         roleName: undefined,
430         roleKey: undefined,
431         roleSort: 0,
432         status: "0",
433         menuIds: [],
434         deptIds: [],
435         menuCheckStrictly: true,
436         deptCheckStrictly: true,
437         remark: undefined
438       };
439       this.resetForm("form");
440     },
441     /** 搜索按钮操作 */
442     handleQuery() {
443       this.queryParams.pageNum = 1;
444       this.getList();
445     },
446     /** 重置按钮操作 */
447     resetQuery() {
448       this.dateRange = [];
449       this.resetForm("queryForm");
450       this.handleQuery();
451     },
452     // 多选框选中数据
453     handleSelectionChange(selection) {
454       this.ids = selection.map(item => item.roleId)
455       this.single = selection.length!=1
456       this.multiple = !selection.length
457     },
458     // 更多操作触发
459     handleCommand(command, row) {
460       switch (command) {
461         case "handleDataScope":
462           this.handleDataScope(row);
463           break;
464         case "handleAuthUser":
465           this.handleAuthUser(row);
466           break;
467         default:
468           break;
469       }
470     },
471     // 树权限(展开/折叠)
472     handleCheckedTreeExpand(value, type) {
473       if (type == 'menu') {
474         let treeList = this.menuOptions;
475         for (let i = 0; i < treeList.length; i++) {
476           this.$refs.menu.store.nodesMap[treeList[i].id].expanded = value;
477         }
478       } else if (type == 'dept') {
479         let treeList = this.deptOptions;
480         for (let i = 0; i < treeList.length; i++) {
481           this.$refs.dept.store.nodesMap[treeList[i].id].expanded = value;
482         }
483       }
484     },
485     // 树权限(全选/全不选)
486     handleCheckedTreeNodeAll(value, type) {
487       if (type == 'menu') {
488         this.$refs.menu.setCheckedNodes(value ? this.menuOptions: []);
489       } else if (type == 'dept') {
490         this.$refs.dept.setCheckedNodes(value ? this.deptOptions: []);
491       }
492     },
493     // 树权限(父子联动)
494     handleCheckedTreeConnect(value, type) {
495       if (type == 'menu') {
496         this.form.menuCheckStrictly = value ? true: false;
497       } else if (type == 'dept') {
498         this.form.deptCheckStrictly = value ? true: false;
499       }
500     },
501     /** 新增按钮操作 */
502     handleAdd() {
503       this.reset();
504       this.getMenuTreeselect();
505       this.open = true;
506       this.title = "添加角色";
507     },
508     /** 修改按钮操作 */
509     handleUpdate(row) {
510       this.reset();
511       const roleId = row.roleId || this.ids
512       const roleMenu = this.getRoleMenuTreeselect(roleId);
513       getRole(roleId).then(response => {
514         this.form = response.data;
515         this.open = true;
516         this.$nextTick(() => {
517           roleMenu.then(res => {
518             let checkedKeys = res.data.checkedKeys
519             checkedKeys.forEach((v) => {
520                 this.$nextTick(()=>{
521                     this.$refs.menu.setChecked(v, true ,false);
522                 })
523             })
524           });
525         });
526         this.title = "修改角色";
527       });
528     },
529     /** 选择角色权限范围触发 */
530     dataScopeSelectChange(value) {
531       if(value !== '2') {
532         this.$refs.dept.setCheckedKeys([]);
533       }
534     },
535     /** 分配数据权限操作 */
536     handleDataScope(row) {
537       this.reset();
538       const deptTreeSelect = this.getDeptTree(row.roleId);
539       getRole(row.roleId).then(response => {
540         this.form = response.data;
541         this.openDataScope = true;
542         this.$nextTick(() => {
543           deptTreeSelect.then(res => {
544             this.$refs.dept.setCheckedKeys(res.data.checkedKeys);
545           });
546         });
547         this.title = "分配数据权限";
548       });
549     },
550     /** 分配用户操作 */
551     handleAuthUser: function(row) {
552       const roleId = row.roleId;
553       this.$router.push("/system/role-auth/user/" + roleId);
554     },
555     /** 提交按钮 */
556     submitForm: function() {
557       this.$refs["form"].validate(valid => {
558         if (valid) {
559           if (this.form.roleId != undefined) {
560             this.form.menuIds = this.getMenuAllCheckedKeys();
561             updateRole(this.form).then(response => {
562               this.$modal.msgSuccess("修改成功");
563               this.open = false;
564               this.getList();
565             });
566           } else {
567             this.form.menuIds = this.getMenuAllCheckedKeys();
568             addRole(this.form).then(response => {
569               this.$modal.msgSuccess("新增成功");
570               this.open = false;
571               this.getList();
572             });
573           }
574         }
575       });
576     },
577     /** 提交按钮(数据权限) */
578     submitDataScope: function() {
579       if (this.form.roleId != undefined) {
580         this.form.deptIds = this.getDeptAllCheckedKeys();
581         dataScope(this.form).then(response => {
582           this.$modal.msgSuccess("修改成功");
583           this.openDataScope = false;
584           this.getList();
585         });
586       }
587     },
588     /** 删除按钮操作 */
589     handleDelete(row) {
590       const roleIds = row.roleId || this.ids;
591       this.$modal.confirm('是否确认删除角色编号为"' + roleIds + '"的数据项?').then(function() {
592         return delRole(roleIds);
593       }).then(() => {
594         this.getList();
595         this.$modal.msgSuccess("删除成功");
596       }).catch(() => {});
597     },
598     /** 导出按钮操作 */
599     handleExport() {
600       this.download('system/role/export', {
601         ...this.queryParams
602       }, `role_${new Date().getTime()}.xlsx`)
603     }
604   }
605 };
606 </script>
607