|
@@ -0,0 +1,217 @@
|
|
|
+<template>
|
|
|
+ <div id="index">
|
|
|
+ <el-row type="flex" :gutter="20">
|
|
|
+ <el-col :span="10">
|
|
|
+ <el-card :body-style="cardStyle">
|
|
|
+ <template #header>
|
|
|
+ <el-row type="flex" justify="space-between" align="middle">
|
|
|
+ <el-col :span="4">角色</el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button type="primary" size="small" @click="toAdd">添加角色</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ <el-table :data="roleList" style="width: 100%" border stripe size="small">
|
|
|
+ <el-table-column align="center" prop="name" label="名称">
|
|
|
+ <template v-slot="{ row }">
|
|
|
+ <div v-if="!row.toEdit">{{ row.name }}</div>
|
|
|
+ <div v-else>
|
|
|
+ <el-input v-model="row.name" size="small"></el-input>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" prop="type" label="类型代码">
|
|
|
+ <template v-slot="{ row }">
|
|
|
+ <div v-if="!row.toEdit">{{ row.type }}</div>
|
|
|
+ <div v-else>
|
|
|
+ <el-input v-model="row.type" size="small"></el-input>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column align="center" prop="name" label="操作">
|
|
|
+ <template v-slot="{ row }">
|
|
|
+ <el-row type="flex" justify="space-around" align="middle">
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button v-if="!row.toEdit" type="text" @click="toUpdate(row)">修改</el-button>
|
|
|
+ <el-button v-else type="text" style="color:#67C23A" @click="toSave(row)">保存</el-button>
|
|
|
+ </el-col>
|
|
|
+ <template v-if="row.id">
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button type="text" style="color:#909399" @click="toSetRoleMenu(row)">权限</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button v-if="!row.disabled" type="text" style="color:#F56C6C" @click="changeDisable(row, true)">禁用</el-button>
|
|
|
+ <el-button v-else type="text" style="color:#67C23A" @click="changeDisable(row, false)">启用</el-button>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button type="text" style="color:#F56C6C" @click="toDelete(row)">删除</el-button>
|
|
|
+ </el-col>
|
|
|
+ </template>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="14">
|
|
|
+ <el-card header="权限" :body-style="cardStyle">
|
|
|
+ <template #header>
|
|
|
+ <el-row type="flex" justify="space-between" align="middle">
|
|
|
+ <el-col :span="4">
|
|
|
+ 权限
|
|
|
+ <span v-if="selectRole.id"> => {{ selectRole.name }} </span>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button type="primary" size="small" v-if="selectRole.id" @click="toSaveMenu">保存 {{ selectRole.name }} 权限</el-button>
|
|
|
+ <el-button type="danger" size="small" v-else :disabled="true">未选择角色</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </template>
|
|
|
+ <el-tree
|
|
|
+ :data="menus"
|
|
|
+ ref="tree"
|
|
|
+ node-key="id"
|
|
|
+ :props="defaultProps"
|
|
|
+ :highlight-current="true"
|
|
|
+ show-checkbox
|
|
|
+ default-expand-all
|
|
|
+ :default-checked-keys="isSelect"
|
|
|
+ >
|
|
|
+ </el-tree>
|
|
|
+ <!-- @check-change="toPermission" -->
|
|
|
+ </el-card>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+const _ = require('lodash');
|
|
|
+import { mapState, createNamespacedHelpers } from 'vuex';
|
|
|
+const { mapActions: menu } = createNamespacedHelpers('menu');
|
|
|
+const { mapActions: role } = createNamespacedHelpers('role');
|
|
|
+export default {
|
|
|
+ name: 'index',
|
|
|
+ props: {},
|
|
|
+ components: {},
|
|
|
+ data: function() {
|
|
|
+ return {
|
|
|
+ cardStyle: {
|
|
|
+ height: '600px',
|
|
|
+ overflowY: 'scroll',
|
|
|
+ },
|
|
|
+ menus: [],
|
|
|
+ roleList: [],
|
|
|
+ selectRole: {},
|
|
|
+ isSelect: [],
|
|
|
+ defaultProps: {
|
|
|
+ children: 'children',
|
|
|
+ label: 'title',
|
|
|
+ },
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.searchRole();
|
|
|
+ this.toFindMenuList();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ ...role(['create', 'update', 'query', 'delete']),
|
|
|
+ ...menu(['findProject']),
|
|
|
+ async searchRole() {
|
|
|
+ const res = await this.query();
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ const { data = [] } = res;
|
|
|
+ this.$set(this, `roleList`, data);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async toFindMenuList() {
|
|
|
+ const res = await this.findProject({ project: this.project });
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ this.$set(this, `menus`, res);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 添加前置
|
|
|
+ toAdd() {
|
|
|
+ this.roleList.push({ toEdit: true });
|
|
|
+ },
|
|
|
+ // 修改前置
|
|
|
+ toUpdate(row) {
|
|
|
+ const index = _.findIndex(this.roleList, row);
|
|
|
+ if (index >= 0) {
|
|
|
+ this.$set(this.roleList, index, { ...row, toEdit: true });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 添加/修改
|
|
|
+ async toSave(data) {
|
|
|
+ const dup = _.cloneDeep(data);
|
|
|
+ const { toEdit, ...info } = dup;
|
|
|
+ if (!toEdit) {
|
|
|
+ console.warn('不能保存未处于编辑状态的数据');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const id = _.get(info, `id`);
|
|
|
+ let res;
|
|
|
+ if (id) {
|
|
|
+ res = await this.update(info);
|
|
|
+ } else {
|
|
|
+ info.project = this.project;
|
|
|
+ res = await this.create(info);
|
|
|
+ }
|
|
|
+ if (this.$checkRes(res, '保存成功', res.errmsg || '保存失败')) {
|
|
|
+ this.searchRole();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 禁用/启用
|
|
|
+ async changeDisable(data, disabled) {
|
|
|
+ let duplicate = _.cloneDeep(data);
|
|
|
+ duplicate.disabled = disabled;
|
|
|
+ const res = await this.update(duplicate);
|
|
|
+ let word = disabled === true ? '禁用' : '启用';
|
|
|
+ if (this.$checkRes(res, `${word}成功`, res.errmsg || `${word}失败`)) {
|
|
|
+ this.searchRole();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 删除
|
|
|
+ async toDelete(data) {
|
|
|
+ this.$confirm(`确定删除${data.name}?`, '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ }).then(async () => {
|
|
|
+ // 直接更新
|
|
|
+ const { _id } = data;
|
|
|
+ let res = await this.delete(_id);
|
|
|
+ if (this.$checkRes(res, '删除成功', res.errmsg || '删除失败')) {
|
|
|
+ this.searchRole();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 设置该角色已选择的权限
|
|
|
+ toSetRoleMenu(data) {
|
|
|
+ const { menu = [] } = data;
|
|
|
+ this.$set(this, `selectRole`, _.cloneDeep(data));
|
|
|
+ this.$refs.tree.setCheckedKeys(menu);
|
|
|
+ },
|
|
|
+ async toSaveMenu() {
|
|
|
+ const selected = this.$refs.tree.getCheckedKeys();
|
|
|
+ let duplicate = _.cloneDeep(this.selectRole);
|
|
|
+ duplicate.menu = selected;
|
|
|
+ const res = await this.update(duplicate);
|
|
|
+ if (this.$checkRes(res, `权限设置成功`, res.errmsg || `权限设置失败`)) {
|
|
|
+ this.searchRole();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['user', 'project']),
|
|
|
+ pageTitle() {
|
|
|
+ return `${this.$route.meta.title}`;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ metaInfo() {
|
|
|
+ return { title: this.$route.meta.title };
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped></style>
|