当前位置: 首页 > article >正文

群控系统服务端开发模式-应用开发-前端管理员功能开发

一、添加视图

        在根目录下src文件夹下views文件夹下permission文件夹下admin文件夹下,新建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-form-item>
                <el-form-item>
                    <el-input v-model="searchParams.username" style="width: 180px;" placeholder="请输入账号名称" clearable/>
                </el-form-item>
                <el-form-item>
                    <el-input v-model="searchParams.email" style="width: 180px;" placeholder="请输入登录账号" clearable/>
                </el-form-item>
                <el-form-item>
                    <el-select
                            v-model="searchParams.role_id"
                            placeholder="请选择角色组"
                    >
                        <el-option v-for="item in roleList" :key="item.id" :label="item.rolename" :value="item.id"/>
                    </el-select>
                </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" style="background:#F2F6FC;"
                               @click="clearSearch">重置
                    </el-button>
                </el-form-item>
            </el-form>
        </div>
        <div class="filter-container" style="float:right;">
            <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexAdd')" class="filter-item" style="margin-left: 10px;" type="primary" @click="handleAdd">添加</el-button>
            <el-button class="filter-item" style="margin-left: 10px;" @click="search(currentPage)">刷新</el-button>
            <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexTostatus')" class="filter-item" style="margin-left: 10px;" @click="handleStatus(1)" type="success">启用</el-button>
            <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexTostatus')" class="filter-item" style="margin-left: 10px;" @click="handleStatus(0)" type="warning">禁用</el-button>
            <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexDelete')" 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}">
                    <span>{{ row.id }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="账号名称">
                <template slot-scope="{row}">
                    <span>{{ row.username }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="登录账号">
                <template slot-scope="{row}">
                    <span>{{ row.email }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="真实名称">
                <template slot-scope="{row}">
                    <span>{{ row.realname }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="头像">
                <template slot-scope="{row}">
                    <div class="demo-image__preview">
                        <el-image style="width:40px;height:40px" :src="row.avatar"/>
                    </div>
                </template>
            </el-table-column>
            <el-table-column align="center" label="角色组">
                <template slot-scope="{row}">
                    <span>{{ row.role_name }}</span>
                </template>
            </el-table-column>
            <el-table-column align="center" label="状态">
                <template slot-scope="{row}">
                    <el-tag type="success" v-if="row.status === 1">启用</el-tag>
                    <el-tag type="warning" v-if="row.status === 0">禁用</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 prop="action" align="center" label="操作" width="210">
                <template slot-scope="{row}">
                    <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexDetails')" size="mini" @click="handleDetails(row.id)" type="info">详情</el-button>
                    <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexEdit')" size="mini" @click="handleEdit(row.id)" type="primary">编辑</el-button>
                    <el-button v-if="$store.getters.butts.includes('PermissionAdminIndexDelete') && row.id > 1" size="mini" @click="handleDelete(row.id)" type="danger">删除</el-button>
                </template>
            </el-table-column>
        </el-table>
        <div class="block">
            <el-pagination
                    :hide-on-single-page="true"
                    :current-page="currentPage"
                    :page-sizes="pageSizes"
                    :page-size="currentSize"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="dataTotal"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
            />
        </div>
        <transition name="dialog-fade">
            <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-position="right" label-width="100px">
                    <el-form-item label="角色分组" prop="role_id" class="roleId">
                        <el-select
                                v-model="resTemp.role_id"
                                placeholder="请选择角色组"
                        >
                            <el-option v-for="item in roleList" :key="item.id" :label="item.rolename" :value="item.id"/>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="账号名称" prop="username">
                        <el-input v-model="resTemp.username" placeholder="账号名称必须填写"/>
                    </el-form-item>
                    <el-form-item label="登录账号" prop="email">
                        <el-input v-model="resTemp.email" placeholder="登录账号必须是邮箱形式"/>
                    </el-form-item>
                    <el-form-item label="密码" prop="password">
                        <el-input :placeholder="resTemp.id === 0 ? '密码必须是两种形式以上' : '留空则不修改'" v-model="resTemp.password"
                                  show-password/>
                    </el-form-item>
                    <el-form-item label="确认密码" prop="confirm_password">
                        <el-input :placeholder="resTemp.id === 0 ? '请再次输入密码' : '留空则不修改'"
                                  v-model="resTemp.confirm_password" show-password/>
                    </el-form-item>
                    <el-form-item label="头像" prop="avatar">
                        <el-upload
                                :action="action"
                                :headers="customHeaders"
                                list-type="picture-card"
                                :on-success="uploadSuccess"
                                :on-error="uploadError"
                                :show-file-list="false"
                                :before-upload="beforeUpload"
                                :accept="imageAccept"
                                :on-progress="uploadProcess"
                                :data="uploadData"
                        >
                            <img v-if="resTemp.avatar != '' && !uploadFlag" ref="avatar" :src="resTemp.avatar" style="width:148px;height:148px;">
                            <i v-else-if="resTemp.avatar =='' && !uploadFlag" class="el-icon-plus"></i>
                            <el-progress v-if="uploadFlag == true" type="circle" :percentage="uploadPercent" style="width:148px;height:148px;margin:10px 0 0 10px;"></el-progress>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="部门" prop="department_id">
                        <el-radio-group v-model="resTemp.department_id">
                            <el-radio-button v-for="item in departmentList" :key="item.id" :label="item.id">{{item.title}}</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="数据级别" prop="grade_id">
                        <el-radio-group v-model="resTemp.grade_id">
                            <el-radio-button v-for="item in gradeList" :key="item.id" :label="item.id">{{item.title}}</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="真实姓名" prop="realname">
                        <el-input v-model="resTemp.realname" placeholder="真实姓名必须填写"/>
                    </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('PermissionAdminIndexSave')" type="primary"
                               @click="saveInfo()">提交
                    </el-button>
                </div>
            </el-dialog>
        </transition>
        <transition name="dialog-fade">
            <el-dialog :visible.sync="dialogDetails" title="详情" :close-on-click-modal="false" :close-on-press-escape="false">
                <el-form ref="resForm" :model="resTemp" label-position="right" label-width="100px">
                    <el-form-item label="角色分组" prop="role_id" class="roleId">
                        <el-select
                                v-model="resTemp.role_id"
                                placeholder="请选择角色组"
                                disabled
                        >
                            <el-option v-for="item in roleList" :key="item.id" :label="item.rolename" :value="item.id"/>
                        </el-select>
                    </el-form-item>
                    <el-form-item label="账号名称" prop="username">
                        <el-input v-model="resTemp.username" placeholder="账号名称必须填写" disabled />
                    </el-form-item>
                    <el-form-item label="登录账号" prop="email">
                        <el-input v-model="resTemp.email" placeholder="登录账号必须是邮箱形式" disabled />
                    </el-form-item>
                    <el-form-item label="头像" prop="avatar">
                        <el-upload
                                :action="action"
                                :headers="customHeaders"
                                list-type="picture-card"
                                :on-success="uploadSuccess"
                                :on-error="uploadError"
                                :show-file-list="false"
                                :before-upload="beforeUpload"
                                :accept="imageAccept"
                                :on-progress="uploadProcess"
                                :data="uploadData"
                                disabled
                        >
                            <img v-if="resTemp.avatar != '' && !uploadFlag" ref="avatar" :src="resTemp.avatar" style="width:148px;height:148px;">
                            <i v-else-if="resTemp.avatar =='' && !uploadFlag" class="el-icon-plus"></i>
                            <el-progress v-if="uploadFlag == true" type="circle" :percentage="uploadPercent" style="width:148px;height:148px;margin:10px 0 0 10px;"></el-progress>
                        </el-upload>
                    </el-form-item>
                    <el-form-item label="部门" prop="department_id">
                        <el-radio-group v-model="resTemp.department_id" disabled >
                            <el-radio-button v-for="item in departmentList" :key="item.id" :label="item.id">{{item.title}}</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="数据级别" prop="grade_id">
                        <el-radio-group v-model="resTemp.grade_id" disabled >
                            <el-radio-button v-for="item in gradeList" :key="item.id" :label="item.id">{{item.title}}</el-radio-button>
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item label="真实姓名" prop="realname">
                        <el-input v-model="resTemp.realname" placeholder="真实姓名必须填写" disabled />
                    </el-form-item>
                    <el-form-item label="状态" prop="status">
                        <el-switch
                                v-model="resTemp.status"
                                active-value="1"
                                inactive-value="0"
                                disabled
                        />
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <el-button @click="dialogDetails=false">取消</el-button>
                </div>
            </el-dialog>
        </transition>
    </div>
</template>
<script>
    import {validEmail, validPassword} from '@/utils/validate'
    import {err, succ, warn} from '@/utils/message'
    import { deleteInfo, getInfo, getList, saveInfo, statusInfo } from '@/api/permission/admin'
    import { getAll } from '@/api/permission/role'
    import { getAll as getDepartmentAll } from '@/api/param/department'
    import { getAll as getGradeAll } from '@/api/param/grade'
    import { get_info } from '@/api/param/upload'
    import {getToken} from '@/utils/auth'
    import Encrypt from 'encryptlong' // encryptlong是基于jsencrypt扩展的长文本分段加解密功能。
    const baseUrl = process.env.VUE_APP_BASE_API
    export default {
        name: 'PermissionAdminIndex', // 名空间
        // 初始化数据
        data() {
            const validateEmail = (rule, value, callback) => {
                if (!validEmail(value)) {
                    callback(new Error('请输入正确的邮箱'))
                } else {
                    callback()
                }
            }
            // 密码验证 添加时必须填写 编辑时如果没有填写则不修改,填写了则修改
            const validatePassword = (rule, value, callback) => {
                if (this.resTemp.id === 0) {
                    if (value === '') {
                        callback(new Error('请填写密码'))
                    } else {
                        const pwRel = validPassword(value)
                        if (pwRel !== true) {
                            callback(new Error(pwRel))
                        } else {
                            callback()
                        }
                    }
                } else {
                    if (value !== undefined && value !== '') {
                        const pwRel = validPassword(value)
                        if (pwRel !== true) {
                            callback(new Error(pwRel))
                        } else {
                            callback()
                        }
                    } else {
                        callback()
                    }
                }
            }
            // 确认密码验证 添加时必须填写 编辑时如果没有填写则不验证,填写了且密码也填写了才与密码配对
            const validateConfirmPassword = (rule, value, callback) => {
                if (this.resTemp.id === 0) {
                    if (value === '') {
                        callback(new Error('请再次输入密码'))
                    } else {
                        if (value !== this.resTemp.password) {
                            callback(new Error('两次密码不一致,请重新输入'))
                        } else {
                            callback()
                        }
                    }
                } else {
                    if (value !== undefined && this.resTemp.password !== undefined) {
                        if (value !== this.resTemp.password) {
                            callback(new Error('两次密码不一致,请重新输入'))
                        } else {
                            callback()
                        }
                    } else {
                        callback()
                    }
                }
            }
            return {
                customHeaders:{
                    Authorization: ""
                },
                upload_number: 0,//最大上传大小
                uploadFlag:false,//上传是否显示滚动条
                uploadPercent:"",//上传滚动条进度
                action:baseUrl + '/upload/file', //用来强制刷新
                imageAccept:'',//图片上传类型
                imageOptions: [],//图片类型
                uploadData:{type:'image'},
                list: [], // 初始化管理员列表
                roleList: [], // 初始化权限组列表
                departmentList: [], // 初始化部门列表
                gradeList: [], // 初始化数据级别列表
                pageSizes: [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500],
                currentPage: 1, // 当前页数
                currentSize: 10, // 每页条数
                dataTotal: 0, // 总数据
                searchParams: {
                    id: '',
                    username: '',
                    email: '',
                    role_id: ''
                },
                // 要提交数据
                resTemp: {
                    id: 0, // 0 添加 >0 编辑
                    username: '',
                    email: '',
                    password: '',
                    confirm_password: '',
                    avatar: '',
                    realname: '',
                    status: '1',
                    department_id: 1,
                    grade_id:1,
                    role_id: 1
                },
                // 要验证数据
                formRules: {
                    role_id: [{required: true, trigger: 'change', message: '权限必须选择'}],
                    username: [
                        {required: true, trigger: 'blur', message: '账号名称必须填写'},
                        {min: 2, max: 40, message: '长度在 2 到 40 个字符', trigger: 'blur'}
                    ],
                    email: [{required: true, trigger: 'blur', validator: validateEmail}],
                    password: [{required: true, trigger: 'blur', validator: validatePassword}],
                    confirm_password: [{required: true, trigger: 'blur', validator: validateConfirmPassword}],
                    avatar: [{required: true, trigger: 'blur', message: '头像必须上传'}],
                    department_id: [{required: true, trigger: 'change', message: '部门必须选择'}],
                    grade_id: [{required: true, trigger: 'change', message: '数据级别必须选择'}],
                    realname: [
                        {required: true, trigger: 'blur', message: '真实名称必须填写'},
                        {min: 2, max: 30, message: '长度在 2 到 30 个字符', trigger: 'blur'}
                    ],
                },
                listLoading: true, // 显示list加载框
                dialogVisible: false, // 初始化弹窗是否显示
                dialogDetails: false
            }
        },
        // 初始化执行的
        created() {
            this.getList()// 获取管理员数据
            this.getAll()// 获取权限组数据
            this.getParamUpload()// 获取参数上传数据
            this.accToken()// 获取token
            this.getDepartmentAll(); // 获取部门
            this.getGradeAll(); // 获取数据级别
        },
        // 所有的方法都需要放到这个里面
        methods: {
            // 搜索
            search() {
                this.getList(1)
            },
            // 管理员数据 --异步
            async getList(page = 0) {
                this.listLoading = true
                const params = {
                    currentPage: page === 0 ? this.currentPage : page,
                    currentSize: this.currentSize,
                    ...this.searchParams
                }
                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 lists = await getAll()
                this.roleList = lists.data
            },
            // 部门数据 --异步
            async getDepartmentAll(){
                const lists = await getDepartmentAll()
                this.departmentList = lists.data
            },
            // 数据级别 --异步
            async getGradeAll(){
                const lists = await getGradeAll()
                this.gradeList = lists.data
            },
            //token生成
            accToken(){
                // 公钥key
                const publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYW5f4L5yz1myyGXrvEmrAlfpV\n" +
                    "HHRrZKsYdAGBvx0IHRV3zwCnACAFnpBQqfreZX3TKUBbA7Kfyh1XG7ytW6reBGLO\n" +
                    "xjJC2SncYXjtEydCMdjMaY0BSAV2J9238If5K5htt0pGWkUVt6BnTPAWUDzwRYQN\n" +
                    "XZaDIIkQ1yBLvJPfQQIDAQAB";
                const PUBLIC_KEY = publicKey
                var encryptor = new Encrypt()
                encryptor.setPublicKey(PUBLIC_KEY)
                // 如果是对象/数组的话,需要先JSON.stringify转换成字符串
                var Base64 = require('js-base64').Base64
                this.customHeaders.Authorization= encryptor.encryptLong(Base64.decode(getToken()))
            },
            //获取上传文件
            async getParamUpload() {
                await get_info({id: 1}).then(res => {
                    var row = res.data
                    const checkedImage = row.checked_images.split(',')// 拆分成数组
                    for (let i=0;i<checkedImage.length;i++){
                        if(checkedImage[i].length <= 3){
                            this.imageOptions.push('.'+checkedImage[i]);
                        }else{
                            this.imageOptions.push(checkedImage[i]);
                        }
                        this.imageAccept += '.'+checkedImage[i]+',';
                    }
                    this.upload_number = row.upload_number * 1;
                })
            },
            // 清除搜索功能
            clearSearch() {
                this.searchParams = {
                    id: '',
                    username: '',
                    email: '',
                    role_id: ''
                }
                this.getList()
            },
            // 重置表单数据 ---添加时候需要使用
            resetTemp() {
                this.resTemp = {
                    id: 0, // 0 添加 >0 编辑
                    username: '',
                    realname: '',
                    email: '',
                    password: '',
                    confirm_password: '',
                    avatar: '',
                    status: '1',
                    department_id: 1,
                    grade_id: 1,
                    role_id: 1
                }
            },
            // 添加方法
            handleAdd() {
                this.resetTemp()
                this.dialogVisible = true
                this.$nextTick(() => {
                    this.$refs['resForm'].clearValidate()
                })
            },
            // 编辑方法
            handleEdit(id) {
                getInfo({id: id}).then(res => {
                    const row = res.data
                    this.resTemp = Object.assign({}, row)
                    this.resTemp.status = row.status + ''// 将数字强行转换成字符串
                    this.dialogVisible = true
                    this.$nextTick(() => {
                        this.$refs['resForm'].clearValidate()
                    })
                })
            },
            // 详情
            handleDetails(id){
                getInfo({ id: id }).then(res => {
                    const row = res.data
                    this.resTemp = Object.assign({}, row)
                    this.resTemp.status = row.status + ''// 将数字强行转换成字符串
                    this.dialogDetails = true
                    this.$nextTick(() => {
                        this.$refs['resForm'].clearValidate()
                    })
                })
            },
            // 禁止选择超级管理员账户
            canSelect(row) {
                return row.id === 1 ? 0 : 1
            },
            // 新建保存数据
            async saveInfo() {
                this.$refs.resForm.validate(valid => {
                    if (valid) {
                        this.loading = true
                        saveInfo(this.resTemp).then(res => {
                            this.loading = false
                            succ(res.message)
                            this.getList()
                            this.dialogVisible = false
                        })
                    } else {
                        return false
                    }
                })
            },
            // 删除
            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
                })
            },
            // 每页条数切换
            handleSizeChange(val) {
                this.currentSize = val
                this.getList()
            },
            // 页数切换
            handleCurrentChange(val) {
                this.currentPage = val
                this.getList()
            },
            // 上传前验证
            beforeUpload(file) {
                let fileName = file.name;
                let fileType = fileName.substring(fileName.length*1 - 4,fileName.length);
                if(this.imageOptions.findIndex((v)=>(v===fileType)) === -1){
                    err('图片格式只能是 JPG|png|gif 格式!')
                    return false
                }
                const isLt3M = file.size / 1024 / 1024 < this.upload_number
                if (!isLt3M) {
                    err('上传文件大小不能超过'+this.upload_number+'MB!')
                    return false
                }
            },
            //上传进度条
            uploadProcess(event, file){
                this.uploadFlag = true;
                this.uploadPercent = file.percentage.toFixed(0)*1;
                this.accToken()//获取token
            },
            //上传成功提醒
            uploadSuccess(res){
                this.uploadFlag = false;
                this.uploadPercent = 0;
                if(res.code == 20000){
                    this.resTemp.avatar = res.data.url
                    succ(res.message)
                }else{
                    err(res.message)
                }
                return false
            },
            //上传错误提醒
            uploadError(er){
                if(er != ''){
                    err('上传失败')
                }
                return false
            }
        }
    }
</script>
<style lang="scss" scoped>
    .app-container {
        padding: 10px;
        .roles-table {
            margin-top: 30px;
        }
        .permission-tree {
            margin-bottom: 30px;
        }
    }
    .el-image-viewer__close {
        color: #fff;
    }
    .roleId .el-select {
        width: 100%;
    }
    .avatar-uploader {
        border: 1px dotted #d9d9d9;
        border-radius: 6px;
        cursor: pointer;
        position: relative;
        overflow: hidden;
        width: 102px;
        height: 102px;
    }
    .avatar-uploader:hover {
        border-color: #409EFF;
    }
    .avatar-uploader-icon {
        font-size: 28px;
        color: #8c939d;
        width: 100px;
        height: 100px;
        line-height: 100px;
        text-align: center;
    }
    .avatar {
        width: 100px;
        height: 100px;
        border: 1px dotted #d9d9d9;
        cursor: pointer;
        display: block;
    }
</style>

二、添加ajax请求

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

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

http://www.kler.cn/a/400526.html

相关文章:

  • 编程语言02:语法基础
  • Linux Kernel Programming 2
  • 理解 Python 中的 __getitem__ 方法:在自定义类中启用索引和切片操作
  • ASP.NET Core Webapi 返回数据的三种方式
  • 3. langgraph中的react agent使用 (在react agent添加系统提示)
  • 抖音热门素材去哪找?优质抖音视频素材网站推荐!
  • BLE 蓝牙客户端和服务器连接
  • 纯前端实现语音文字互转
  • 大模型实操练习二、文心大模型API使用方法(入门阶段)
  • 离散数学笔记
  • 【ASR技术】WhisperX安装使用
  • 【论文阅读】InstructPix2Pix: Learning to Follow Image Editing Instructions
  • 键盘上打出反引号符号(´),即单个上标的撇号(这个符号与反引号 ` 不同,反引号通常位于键盘的左上角)
  • DBeaver MACOS 安装 并连接到docker安装的mysql
  • Android 开发与救砖工具介绍
  • Fisher矩阵和Hessian矩阵的关系:证明Fisher为负对数似然函数的Hessian的期望
  • LeetCode 2816.翻倍以链表形式表示的数字
  • 消息队列原理面试题及参考答案
  • 手搓神经网络(MLP)解决MNIST手写数字识别问题 | 数学推导+代码实现 | 仅用numpy,tensor和torch基本计算 | 含正反向传播数学推导
  • 开源控件:Qt/C++自定义颜色组合框控件ColorComboBox
  • 深度学习:循环神经网络的计算复杂度,顺序操作和最大路径长度
  • Spring Boot汽车资讯:科技与速度的新纪元
  • Leetcode 逆波兰表达式求值
  • Redis与数据库关联小记
  • 连续 Hopfield 神经网络深入探讨
  • Git学习教程(更新中)