|
@@ -0,0 +1,252 @@
|
|
|
+<template>
|
|
|
+ <div id="index">
|
|
|
+ <detail-frame :title="pageTitle" v-if="view == 'list'">
|
|
|
+ <el-row type="flex" justify="end" align="middle">
|
|
|
+ <el-col :span="4">
|
|
|
+ <el-button type="primary" size="small" @click="dialog = true">添加管理员用户</el-button>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <data-table
|
|
|
+ :fields="fields"
|
|
|
+ :data="list"
|
|
|
+ :opera="opera"
|
|
|
+ :total="total"
|
|
|
+ :toFormat="toFormat"
|
|
|
+ @query="search"
|
|
|
+ @edit="toEdit"
|
|
|
+ @freeze="data => toStatus(data, '2')"
|
|
|
+ @unfreeze="data => toStatus(data, '1')"
|
|
|
+ @toRoleMenu="toRoleMenu"
|
|
|
+ >
|
|
|
+ <template #options="{item}">
|
|
|
+ <template v-if="item.prop === 'type'">
|
|
|
+ <el-option v-for="(i, index) in roleList" :key="`role-${index}`" :label="i.name" :value="i.type"></el-option>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ <template #custom="{item,row}">
|
|
|
+ <template v-if="item.prop === 'openid'">
|
|
|
+ <span :style="{ color: `${row[item.prop] ? '#67C23A' : '#F56C6C'}` }">{{ row[item.prop] ? '已绑定' : '未绑定' }}</span>
|
|
|
+ </template>
|
|
|
+ </template>
|
|
|
+ </data-table>
|
|
|
+ </detail-frame>
|
|
|
+ <detail-frame :title="roleTitle" :returns="() => (view = 'list')" v-else>
|
|
|
+ <el-card header="权限" :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="toSaveMenu">保存</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>
|
|
|
+ </el-card>
|
|
|
+ </detail-frame>
|
|
|
+
|
|
|
+ <el-dialog :visible.sync="dialog" title="添加管理员" @close="toClose" width="30%" :destroy-on-close="true">
|
|
|
+ <data-form :data="form" :fields="formFields" :rules="rules" @save="toSave"> </data-form>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+const _ = require('lodash');
|
|
|
+import dataForm from '@frame/components/form';
|
|
|
+import dataTable from '@frame/components/filter-page-table';
|
|
|
+import detailFrame from '@frame/layout/admin/detail-frame';
|
|
|
+import { mapState, createNamespacedHelpers } from 'vuex';
|
|
|
+const { mapActions: users } = createNamespacedHelpers('user');
|
|
|
+const { mapActions: role } = createNamespacedHelpers('role');
|
|
|
+const { mapActions: menu } = createNamespacedHelpers('menu');
|
|
|
+const { mapActions: userMenu } = createNamespacedHelpers('userMenu');
|
|
|
+export default {
|
|
|
+ name: 'index',
|
|
|
+ props: {},
|
|
|
+ components: { dataTable, detailFrame, dataForm },
|
|
|
+ data: function() {
|
|
|
+ return {
|
|
|
+ view: 'list',
|
|
|
+ opera: [
|
|
|
+ {
|
|
|
+ label: '用户权限',
|
|
|
+ method: 'toRoleMenu',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '编辑',
|
|
|
+ method: 'edit',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '冻结账号',
|
|
|
+ display: i => i.status !== '2',
|
|
|
+ method: 'freeze',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '解除冻结',
|
|
|
+ display: i => !(i.status !== '2'),
|
|
|
+ method: 'unfreeze',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ fields: [
|
|
|
+ { label: '用户名', prop: 'name', filter: true },
|
|
|
+ { label: '登录名', prop: 'mobile' },
|
|
|
+ { label: '密码', prop: 'passwd' },
|
|
|
+ { label: '是否绑定微信', prop: 'openid', custom: true },
|
|
|
+ { label: '角色', prop: 'type', format: true, filter: 'select' },
|
|
|
+ { label: '备注', prop: 'remark' },
|
|
|
+ { label: '状态', prop: 'status', format: i => (i !== '2' ? '使用中' : '冻结') },
|
|
|
+ ],
|
|
|
+ dialog: false,
|
|
|
+ form: {},
|
|
|
+ formFields: [
|
|
|
+ { label: '用户名', required: false, model: 'name' },
|
|
|
+ { label: '登录名', required: true, model: 'mobile' },
|
|
|
+ { label: '密码', required: true, model: 'passwd' },
|
|
|
+ { label: '备注', required: false, model: 'remark', type: 'textarea' },
|
|
|
+ ],
|
|
|
+ rules: {
|
|
|
+ mobile: [{ required: true, message: '请输入登陆名' }],
|
|
|
+ passwd: [{ required: true, message: '请输入密码' }],
|
|
|
+ },
|
|
|
+ list: [],
|
|
|
+ total: 0,
|
|
|
+ roleList: [],
|
|
|
+ // 角色权限部分
|
|
|
+ cardStyle: {
|
|
|
+ height: '600px',
|
|
|
+ overflowY: 'scroll',
|
|
|
+ },
|
|
|
+ roleTitle: '',
|
|
|
+ menus: [],
|
|
|
+ isSelect: [],
|
|
|
+ defaultProps: {
|
|
|
+ children: 'children',
|
|
|
+ label: 'title',
|
|
|
+ },
|
|
|
+ selectUser: {},
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.toGetRoleList();
|
|
|
+ this.search();
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ ...users(['create', 'update', 'query', 'update']),
|
|
|
+ ...role({ getRoleList: 'query', roleMenu: 'roleMenu' }),
|
|
|
+ ...userMenu({ createUserMenu: 'create' }),
|
|
|
+ // 查找角色
|
|
|
+ async search({ skip = 0, limit = 10, ...info } = {}) {
|
|
|
+ const res = await this.query({ skip, limit, ...info });
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ this.$set(this, `list`, res.data);
|
|
|
+ this.$set(this, `total`, res.total);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //编辑角色
|
|
|
+ toEdit({ data }) {
|
|
|
+ this.$set(this, `form`, _.cloneDeep(data));
|
|
|
+ this.dialog = true;
|
|
|
+ },
|
|
|
+ //添加/修改角色
|
|
|
+ async toSave({ data }) {
|
|
|
+ const { _id } = data;
|
|
|
+ let res;
|
|
|
+ if (_id) {
|
|
|
+ res = this.update(data);
|
|
|
+ } else {
|
|
|
+ data.type = '0';
|
|
|
+ res = this.create(data);
|
|
|
+ }
|
|
|
+ if (this.$checkRes(res, `操作成功`, res.errmsg || '操作失败')) {
|
|
|
+ this.toClose();
|
|
|
+ this.search();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 更换角色状态
|
|
|
+ async toStatus({ data }, status) {
|
|
|
+ data.status = status;
|
|
|
+ const res = this.update(data);
|
|
|
+ const word = status === '2' ? '冻结' : '解冻';
|
|
|
+ if (this.$checkRes(res, `${word}成功`, res.errmsg || `${word}失败`)) {
|
|
|
+ this.search();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //获取指定用户的菜单,进入该用户权限编辑页面
|
|
|
+ async toRoleMenu({ data }) {
|
|
|
+ if (!data.type) {
|
|
|
+ this.$message.error('未找到用户角色');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const { name, _id } = data;
|
|
|
+ let obj = { type: data.type, project: 'center', userid: _id };
|
|
|
+ const res = await this.roleMenu(obj);
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ let { selected, menu } = res.data;
|
|
|
+ this.$set(this, `menus`, menu);
|
|
|
+ this.$set(this, `isSelect`, selected);
|
|
|
+ this.$set(this, `selectUser`, _.cloneDeep(data));
|
|
|
+ this.$set(this, `roleTitle`, `${name} => 权限设置`);
|
|
|
+ this.view = 'tree';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 保存该用户非角色权限
|
|
|
+ async toSaveMenu() {
|
|
|
+ // 所有已经选择的菜单(包括角色部分)
|
|
|
+ const selected = this.$refs.tree.getCheckedKeys();
|
|
|
+ let duplicate = _.cloneDeep(this.isSelect);
|
|
|
+ const needSave = _.difference(selected, duplicate);
|
|
|
+ let obj = { project: 'center', menu: needSave };
|
|
|
+ if (!this.selectUser._id) {
|
|
|
+ this.$message.error('未找到该用户的信息');
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ obj.userid = this.selectUser._id;
|
|
|
+ const res = await this.createUserMenu(obj);
|
|
|
+ this.$checkRes(res, '保存成功', res.errmsg || '保存失败');
|
|
|
+ },
|
|
|
+ toFormat({ model, value }) {
|
|
|
+ if (model === 'type') {
|
|
|
+ const r = this.roleList.find(f => f.type == value);
|
|
|
+ if (r) {
|
|
|
+ return r.name || '';
|
|
|
+ } else {
|
|
|
+ return '未设置的角色';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ toClose() {
|
|
|
+ this.dialog = false;
|
|
|
+ this.form = {};
|
|
|
+ },
|
|
|
+ async toGetRoleList() {
|
|
|
+ const res = await this.getRoleList();
|
|
|
+ if (this.$checkRes(res)) {
|
|
|
+ this.$set(this, `roleList`, res.data);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['user']),
|
|
|
+ pageTitle() {
|
|
|
+ return `${this.$route.meta.title}`;
|
|
|
+ },
|
|
|
+ },
|
|
|
+ metaInfo() {
|
|
|
+ return { title: this.$route.meta.title };
|
|
|
+ },
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped></style>
|