自学内容网 自学内容网

群控系统服务端开发模式-应用开发-前端角色功能开发

一、添加视图

        在根目录下src文件夹下views文件夹下permission文件夹下role文件夹下,新建index.vue,代码如下

<template>
    <div class="app-container"><div class="filter-container" style="float:left;">
        <el-form :inline="true" :model="searchParams" class="demo-form-inline">
            <el-form-item>
                <el-input v-model="searchParams.id" style="width: 160px;" placeholder="请输入ID" clearable></el-input>
            </el-form-item>
            <el-form-item>
                <el-input v-model="searchParams.rolename" style="width: 180px;" placeholder="请输入角色组名称" clearable></el-input>
            </el-form-item>
            <el-form-item>
                <el-input v-model="searchParams.role_key" style="width: 180px;" placeholder="请输入Key" clearable></el-input>
            </el-form-item>
            <el-form-item>
                <el-button class="search-btn el-button--infoSearch" type="primary" @click="search()">搜索</el-button>
                <el-button class="search-btn el-button--infoSearch" @click="clearSearch" style="background:#F2F6FC;">重置</el-button>
            </el-form-item>
        </el-form>
    </div>
        <div class="filter-container" style="float:right;">
            <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexAdd')" class="filter-item" style="margin-left: 10px;" type="primary" @click="handleAdd">添加</el-button>
            <el-button class="filter-item" style="margin-left: 10px;" @click="search()">刷新</el-button>
            <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexTostatus')" class="filter-item" style="margin-left: 10px;" @click="handleStatus(1)" type="success">启用</el-button>
            <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexTostatus')" class="filter-item" style="margin-left: 10px;" @click="handleStatus(0)" type="warning">禁用</el-button>
            <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexDelete')" class="filter-item" @click="handleDelete" type="danger">删除</el-button>
        </div>
        <el-table
                ref="resTable"
                v-loading="listLoading"
                :data="list"
                row-key="id"
                highlight-current-row
                max-height="750"
                default-expand-all
                style="width: 100%;margin-top:10px;"
                border
                :default-sort = "{prop: 'id', order: 'descending'}"
        >
            <el-table-column type="selection" width="50" align="center" :selectable="canSelect" />
            <el-table-column align="center" label="ID" sortable prop="id">
                <template slot-scope="{row}">
                    {{ row.id }}
                </template>
            </el-table-column>
            <el-table-column align="center" label="Key(前端权限标识)">
                <template slot-scope="{row}">
                    {{ row.role_key }}
                </template>
            </el-table-column>
            <el-table-column align="center" label="角色组名称">
                <template slot-scope="{row}">
                    <el-tag>{{ row.rolename }}</el-tag>
                </template>
            </el-table-column>
            <el-table-column align="center" label="菜单组" :show-overflow-tooltip='true'>
                <template slot-scope="{row}">
                    {{ row.menus }}
                </template>
            </el-table-column>
            <el-table-column align="center" label="状态">
                <template slot-scope="{row}">
                    <el-tag>{{ row.status === 1 ? '启用' : '禁用' }}</el-tag>
                </template>
            </el-table-column>
            <el-table-column align="center" label="添加时间">
                <template slot-scope="{row}">
                    <span>{{ row.create_time }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="修改时间">
                <template slot-scope="{row}">
                    <span>{{ row.update_time }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="操作" width="210">
                <template slot-scope="{row}">
                    <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexDetails')" size="mini" @click="handleDetails(row.id)" type="info">详情</el-button>
                    <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexEdit')" type="primary" size="small" @click="handleEdit(row.id)">编辑</el-button>
                    <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexDelete') && row.role_key != 'SuperAdmin'" size="small" @click="handleDelete(row.id)" type="danger">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <div class="block">
            <el-pagination
                    :hide-on-single-page="true"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                    :current-page="currentPage"
                    :page-sizes="pageSizes"
                    :page-size="currentSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="dataTotal">
            </el-pagination>
        </div>
        <el-dialog :visible.sync="dialogVisible" :title="resTemp.id === 0 ? '添加' : '编辑'" :close-on-click-modal="false" :close-on-press-escape="false">
            <el-form ref="resForm" :rules="formRules" :model="resTemp" label-width="80px" label-position="left">
                <el-form-item label="名称" prop="rolename">
                    <el-input v-model="resTemp.rolename" placeholder="请输入名称" />
                </el-form-item>
                <el-form-item label="Key" prop="role_key">
                    <el-input v-model="resTemp.role_key" placeholder="请输入角色组Key" v-if="resTemp.role_key != 'SuperAdmin'" />
                    <el-input v-model="resTemp.role_key" placeholder="请输入角色组Key" v-if="resTemp.role_key == 'SuperAdmin'" disabled />
                </el-form-item>
                <el-form-item label="路由菜单" prop="rules">
                    <el-tree
                            ref="tree"
                            :data="routes"
                            :props="defaultProps"
                            show-checkbox
                            node-key="id"
                    >
                    </el-tree>
                </el-form-item>
                <el-form-item label="状态" prop="status">
                    <el-switch
                            v-model="resTemp.status"
                            active-value="1"
                            inactive-value="0">
                    </el-switch>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible=false">取消</el-button>
                <el-button v-if="$store.getters.butts.includes('PermissionRoleIndexSave')" type="primary" @click="saveInfo()">提交</el-button>
            </div>
        </el-dialog>
        <el-dialog :visible.sync="dialogDetails" title="详情" :close-on-click-modal="false" :close-on-press-escape="false">
            <el-form ref="resDetailsForm" :model="resDetailsTemp" label-width="80px" label-position="left">
                <el-form-item label="名称">
                    <el-input v-model="resDetailsTemp.rolename" placeholder="请输入名称" disabled />
                </el-form-item>
                <el-form-item label="Key">
                    <el-input v-model="resDetailsTemp.role_key" placeholder="请输入角色组Key" disabled />
                </el-form-item>
                <el-form-item label="路由菜单">
                    <el-tree
                            ref="treeDetails"
                            :data="routesDetails"
                            :props="defaultProps"
                            show-checkbox
                            node-key="id"
                    >
                    </el-tree>
                </el-form-item>
                <el-form-item label="状态">
                    <el-switch
                            v-model="resDetailsTemp.status"
                            active-value="1"
                            inactive-value="0"
                            disabled
                    >
                    </el-switch>
                </el-form-item>
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="dialogDetails=false">取消</el-button>
            </div>
        </el-dialog>
    </div>
</template>
<script>
    import path from 'path'
    import { succ, warn, err } from '@/utils/message';
    import { getInfo, getList, saveInfo, deleteInfo, statusInfo } from '@/api/permission/role'
    import { getAll } from '@/api/permission/menu'
    import moment from 'moment'
    export default {
        name: 'PermissionRoleIndex', // 名空间
        data() {
            //角色组验证
            const validateRules = (rule, value, callback) => {
                const checkedKeys = this.$refs.tree.getCheckedKeys()
                if (checkedKeys.length === 0) {
                    callback(new Error('请选择路由菜单'))
                } else {
                    this.resTemp.rules = checkedKeys
                    callback()
                }
            }
            return {
                //要提交数据
                resTemp:{
                    id: 0,//0 添加 >0 编辑
                    rolename:'',
                    role_key:'',
                    rules:[],
                    status:'1'
                },
                resDetailsTemp:{
                    id: 0,//0 添加 >0 编辑
                    rolename:'',
                    role_key:'',
                    rules:[],
                    status:'1'
                },
                routes: [],
                routesDetails: [],
                list: [],
                pageSizes:[10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500],
                currentPage: 1,//当前页数
                currentSize:10,//每页条数
                dataTotal:0,//总数据
                searchParams:{
                    id:'',
                    rolename:'',
                    role_key:''
                },
                //要验证数据
                formRules: {
                    rolename: [
                        { required: true, trigger: 'blur', message: '必须填写' },
                        { min: 2, max: 30, message: '长度在 2 到 30 个字符', trigger: 'blur' }
                    ],
                    role_key: [
                        { required: true, trigger: 'change', message: '角色组Key' },
                        { min: 2, max: 30, message: '长度在 2 到 30 个字符', trigger: 'blur' }
                    ],
                    rules: [
                        { required: true, validator: validateRules, trigger: 'blur' }
                    ],
                },
                listLoading: true,
                dialogVisible: false,
                dialogDetails: false,
                defaultProps: {
                    children: 'children',
                    label: 'title'
                }
            }
        },
        computed: {
        },
        created() {
            this.getList()
            this.getAll(false)// 获取文件类数据
        },
        methods: {
            // 搜索
            search() {
                this.currentPage = 1;
                this.getList(1)
            },
            // 列表
            async getList(page=0) {
                let params = {
                    currentPage:page === 0 ? this.currentPage : page,
                    currentSize:this.currentSize,
                    ...this.searchParams
                };
                this.listLoading = true
                await getList(params).then(res => {
                    this.list = res.data.list
                    this.dataTotal = res.data.meat.total*1;
                    // 延时
                    setTimeout(() => {
                        this.listLoading = false
                    }, 0.5 * 1000)
                })
            },
            // 所有菜单
            async getAll() {
                const res = await getAll()
                this.routes = this.generateRoutes(res.data,'/',false)
            },
            // 重塑路由结构,使其看起来与侧边栏相同
            generateRoutes(routes, basePath = '/',disabled) {
                const res = []
                for (const route of routes) {
                    // 路由是否隐藏
                    if (route.hidden) { continue }
                    const data = {
                        path: path.resolve(basePath, route.path),
                        title: route.title,
                        id: route.id,
                        disabled:disabled
                    }
                    // 子路由处理
                    if (route.children) {
                        data.children = this.generateRoutes(route.children, data.path, disabled)
                    }
                    res.push(data)
                }
                return res
            },
            //重置表单数据 ---添加时候需要使用
            resetTemp() {
                this.resTemp = {
                    id: 0,//0 添加 >0 编辑
                    rolename:'',
                    role_key:'',
                    rules:[],
                    status:'1'
                }
            },
            // 添加
            handleAdd() {
                this.resetTemp()
                this.dialogVisible = true
                this.$nextTick(() => {
                    this.$refs.tree.setCheckedKeys([]);
                    this.$refs.tree.setCheckedNodes([]);
                    this.$refs['resForm'].clearValidate()
                })
            },
            // 编辑
            handleEdit(id) {
                getInfo({id:id}).then(res=>{
                    let row = res.data
                    row.rules = row.menu_id.split(',')
                    this.resTemp = Object.assign({}, row)
                    this.resTemp.status = row.status+''//将数字强行转换成字符串
                    this.$nextTick(() => {
                        //优先清理一下
                        this.$refs.tree.setCheckedKeys([]);
                        this.$refs.tree.setCheckedNodes([]);
                        //清理完毕了再操作
                        row.rules.forEach(item => {
                            this.$refs.tree.getNode(item).checked = true;
                            this.$refs.tree.getNode(item).parent.checked = true;
                            this.$refs.tree.getNode(item).parent.indeterminate = false;
                        })
                        this.$refs['resForm'].clearValidate()
                    })
                    this.dialogVisible = true
                })
            },
            handleDetails(id){
                getAll().then(res => {
                    this.routesDetails = this.generateRoutes(res.data,'/',true)
                    getInfo({id:id}).then(res=>{
                        let row = res.data
                        row.rules = row.menu_id.split(',')
                        this.resDetailsTemp = Object.assign({}, row)
                        this.resDetailsTemp.status = row.status+''//将数字强行转换成字符串
                        this.$nextTick(() => {
                            //优先清理一下
                            this.$refs.treeDetails.setCheckedKeys([]);
                            this.$refs.treeDetails.setCheckedNodes([]);
                            //清理完毕了再操作
                            row.rules.forEach(item => {
                                this.$refs.treeDetails.getNode(item).checked = true;
                                this.$refs.treeDetails.getNode(item).parent.checked = true;
                                this.$refs.treeDetails.getNode(item).parent.indeterminate = false;
                            })
                            this.$refs['resDetailsForm'].clearValidate()
                        })
                        this.dialogDetails = true
                    })
                });
            },
            // 保存
            async saveInfo() {
                this.$refs.resForm.validate(valid => {
                    if(valid) {
                        this.resTemp.menu_id = this.getCheckedKeys(this.routes, this.$refs.tree.getCheckedKeys(), 'id');//重新组合权限
                        this.loading = true
                        saveInfo(this.resTemp).then(res=>{
                            this.loading = false
                            succ(res.message)
                            this.getList()
                            this.dialogVisible = false
                        });
                    } else {
                        return false
                    }
                })
            },
            //内部递归寻找父类组合
            getCheckedKeys (data, keys, key) {
                var res = [];
                recursion(data, false);
                return res;
                // arr -> 树形总数据
                // keys -> getCheckedKeys获取到的选中key值
                // isChild -> 用来判断是否是子节点
                function recursion (arr, isChild) {
                    var aCheck = [];
                    for ( var i = 0; i < arr.length; i++ ) {
                        var obj = arr[i];
                        aCheck[i] = false;
                        if ( obj.children ) {
                            aCheck[i] = recursion(obj.children, true) ? true : aCheck[i];
                            if ( aCheck[i] ) {
                                res.push(obj[key]);
                            }
                        }
                        for ( var j = 0; j < keys.length; j++ ) {
                            if ( obj[key] == keys[j] ) {
                                aCheck[i] = true;
                                if ( res.indexOf(obj[key]) == -1 ) {
                                    res.push(obj[key]);
                                }
                                break;
                            }
                        }
                    }
                    if ( isChild ) {
                        return aCheck.indexOf(true) != -1;
                    }
                }
            },
            //删除
            handleDelete(id) {
                this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning',
                    center: true
                }).then(async() => {
                    const ids = []
                    if(id > 0){//单个删除
                        ids.push(id)
                    }else{//批量删除
                        const select = this.$refs.resTable.selection
                        if(select.length === 0){
                            warn('批量删除必须选择指定产品');
                            return false;
                        }
                        //组合数据
                        select.forEach(item => {
                            ids.push(item.id)
                        })
                    }
                    //删除
                    deleteInfo({id:ids}).then(res=>{
                        this.getList()//更新列表
                        succ(res.message)//提示结果
                    })
                }).catch(err => {
                    err(err.message)
                    return false
                })
            },
            // 启禁用
            handleStatus(status){
                let statusText = status == 1 ? '启用' : '禁用';
                this.$confirm('此操作将永久'+ statusText +'该产品, 是否继续?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning',
                    center: true
                }).then(async() => {
                    const ids = []
                    const select = this.$refs.resTable.selection
                    if (select.length === 0) {
                        warn('批量'+ statusText +'必须选择指定产品')
                        return false
                    }
                    // 组合数据
                    select.forEach(item => {
                        ids.push(item.id)
                    })
                    // 删除
                    statusInfo({ id: ids, status:status }).then(res => {
                        this.getList()//更新列表
                        succ(res.message)// 提示结果
                    })
                }).catch(err => {
                    err(err.message)
                    return false
                })
            },
            // 禁止选择超级管理员组
            canSelect(row) {
                return row.role_key === 'SuperAdmin' ? 0 : 1
            },
            //清除搜索功能
            clearSearch(){
                this.searchParams = {
                    id:'',
                    rolename:'',
                    key:''
                }
                this.currentPage = 1;
                this.getList()
            },
            //条数切换
            handleSizeChange(val) {
                this.currentSize = val;
                this.getList();
            },
            //页数切换
            handleCurrentChange(val) {
                this.currentPage = val;
                this.getList();
            }
        }
    }
</script>
<style lang="scss" scoped>
    .app-container {
        padding:10px;
        .roles-table {
            margin-top: 30px;
        }
        .permission-tree {
            margin-bottom: 30px;
        }
    }
    .el-tooltip__popper{
        max-width:20%;
    }
    .el-tooltip__popper,.el-tooltip__popper.is-dark{
        background:rgb(48, 65, 86) !important;
        color: #fff !important;
        line-height: 24px;
    }
</style>

二、添加ajax请求

        在根目录下src文件夹下api文件夹下permission文件夹下role.js,代码如下

import request from '@/utils/request'
// 列表
export function getList(params) {
    return request({
        url: '/permission/role/get_list',
        method: 'get',
        params:params
    })
}
// 所有
export function getAll() {
    return request({
        url: '/permission/role/get_all',
        method: 'post'
    })
}
// 获取
export function getInfo(data) {
    return request({
        url: '/permission/role/get_info',
        method: 'post',
        data
    })
}
// 保存
export function saveInfo(data) {
    return request({
        url: '/permission/role/save_info',
        method: 'post',
        data
    })
}
// 删除
export function deleteInfo(data) {
    return request({
        url: '/permission/role/delete_info',
        method: 'post',
        data
    })
}
// 启禁用
export function statusInfo(data) {
    return request({
        url: '/permission/role/status_info',
        method: 'post',
        data
    })
}

三、提前说明

        明天将开发岗位配置、级别配置功能。


原文地址:https://blog.csdn.net/m0_63603104/article/details/143769823

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!