vue+elementui常用组件

vue+elementui常用组件

1.表单

目标效果:

前端页面:

<!--顶侧按钮-->
<div class="filter-container">
    <el-input placeholder="档案号/姓名/手机号" v-model="pagination.queryString" style="width: 200px;" class="filter-item"></el-input>
    <el-button @click="_findPage()" class="dalfBut">查询</el-button>
    <el-button type="primary" class="butT" @click="handleCreate()">添加预约</el-button>
</div>
<!--添加预约窗口-->
<div class="add-form">
    <el-dialog title="新增预约" :visible.sync="dialogFormVisible">
        <template>
            <el-tabs v-model="activeName" type="card">
                <el-tab-pane label="基本信息" name="first">
                    <el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px">
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="姓名" prop="name">
                                    <el-input v-model="formData.name"/>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="手机号" prop="telephone">
                                    <el-input v-model="formData.telephone"/>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="预约时间" prop="orderDate">
                                    <el-date-picker
                                                    v-model="formData.orderDate"
                                                    type="date"
                                                    value-format="yyyy-MM-dd"
                                                    placeholder="选择日期">
                                    </el-date-picker>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="出生日期">
                                    <el-date-picker
                                                    v-model="formData.birthday"
                                                    type="date"
                                                    placeholder="选择日期">
                                    </el-date-picker>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="性别">
                                    <el-select v-model="formData.sex">
                                        <el-option label="男" value="1"></el-option>
                                        <el-option label="女" value="2"></el-option>
                                    </el-select>
                                </el-form-item>
                            </el-col>
                            <el-col :span="12">
                                <el-form-item label="年龄">
                                    <el-input v-model="formData.age"/>
                                </el-form-item>
                            </el-col>
                        </el-row>
                        <el-row>
                            <el-col :span="12">
                                <el-form-item label="身份证号">
                                    <el-input v-model="formData.idCard"/>
                                </el-form-item>
                            </el-col>
                        </el-row>
                    </el-form>
                </el-tab-pane>
                <el-tab-pane label="套餐信息" name="second">
                    <el-table
                              :data="tableData"
                              style="width: 100%" >
                        <!--单选-->
                        <el-table-column type="index" label="单选" align="center" width="80px">
                            <template slot-scope="scope">
                                <el-radio v-model="setmealId" :label="scope.row.id" @change="changeRedio($event,scope.row)">&nbsp;</el-radio>
                            </template>
                        </el-table-column>

                        <el-table-column
                                         prop="name"
                                         label="套餐名称"
                                         width=150px>
                        </el-table-column>
                        <el-table-column prop="sex" label="适用人群" width=100px align="center">
                            <template slot-scope="scope">
                                <span v-if="scope.row.sex==0">不限</span>
                                <span v-if="scope.row.sex==1">男</span>
                                <span v-if="scope.row.sex==2">女</span>
                            </template>
                        </el-table-column>
                        <el-table-column
                                         prop="remark"
                                         label="套餐介绍"
                                         width=300px>
                        </el-table-column>
                    </el-table>
                </el-tab-pane>
            </el-tabs>
        </template>
        <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取消</el-button>
            <el-button type="primary" @click="handleAdd()">点击预约</el-button>
        </div>
    </el-dialog>
</div>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            activeName:'first',//添加/编辑窗口Tab标签名称
            formData: {},//表单数据
            tableData:[],//添加表单窗口中套餐数据
            dialogFormVisible: false,//增加表单是否可见
            dialogFormVisible4Edit:false,//编辑表单是否可见
            // setmealIds:[],//添加表单窗口中套餐复选框对应id
            setmealId:'',//添加表单窗口中套餐单选框对应id
            rules: {//校验规则
                name: [{ required: true, message: '姓名为必填项', trigger: 'blur' }],
                telephone: [{ required: true, message: '手机号为必填项', trigger: 'blur' }],
                orderDate: [{ required: true, message: '预约时间为必填项', trigger: 'blur' }]
            }
        },
        methods: {
            // 弹出添加窗口
            handleCreate() {
                this.dialogFormVisible=true;
                this.resetForm();
                //回显所有套餐数据
                axios.post("/setmeal/findAll.do").then((res)=>{
                    this.tableData=res.data.data;
                });
            },
            //添加
            handleAdd () {
                //表单校验
                this.$refs['dataAddForm'].validate((valid)=>{
                    if(valid){
                        //向后台发送ajax请求
                        axios.post("/localOrder/submit.do?setmealId="+this.setmealId,this.formData).then((res)=>{
                            if(res.data.flag){
                                //执行成功
                                this.$message({
                                    type:'success',
                                    message:res.data.message
                                });
                            }else{
                                //执行失败
                                this.$message.error(res.data.message);
                            }
                        }).finally(() => {
                            //关闭添加窗口
                            this.dialogFormVisible=false;
                            //执行分页查询
                            this.findPage();
                        });
                    }else{
                        this.$message.error("表单数据校验失败!");
                        return false;
                    }
                });

            },
            // 重置表单
            resetForm() {
                this.formData={};
                this.activeName = 'first';
                this.setmealId='';
            }
        }
    })
</script>

2.table+单、复选框

后端响应数据:

[
    {"id": 12,"name":"入职无忧体检套餐(男女通用)","sex":"0","remark":"入职体检套餐"},
    {"id": 13,"name":"粉红珍爱(女)升级TM12项筛查体检套餐","sex":"2","remark":"本套餐针对..."},
    ...
 ]

2.1table+单选框

目标效果:

前端页面:

<el-table :data="tableData" style="width: 100%" >
    <!--单选-->
    <el-table-column type="index" label="单选" align="center" width="80px">
        <template slot-scope="scope">
            <!--绑定setmealId-->
            <el-radio v-model="setmealId" :label="scope.row.id" @change="changeRedio($event,scope.row)">&nbsp;</el-radio>
        </template>
    </el-table-column>

    <el-table-column prop="name" label="套餐名称" width=150px></el-table-column>
    <el-table-column prop="sex" label="适用人群" width=100px align="center">
        <template slot-scope="scope">
            <span v-if="scope.row.sex==0">不限</span>
            <span v-if="scope.row.sex==1">男</span>
            <span v-if="scope.row.sex==2">女</span>
        </template>
    </el-table-column>
    <el-table-column prop="remark" label="套餐介绍" width=300px></el-table-column>
</el-table>

<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            tableData:[],//添加表单窗口中套餐数据
            // setmealIds:[],//添加表单窗口中套餐复选框对应id
            setmealId:'',//添加表单窗口中套餐单选框对应id
        },
        methods: {
            //回显数据
            handleUpdate(row) {
                //1.回显所有套餐信息
                axios.get("/setmeal/findAll.do").then((resp)=>{
                    if (resp.data.flag) {
                        this.tableData=resp.data.data;
                    } else {
                        this.$message.error(resp.data.message);
                        return false;
                    }
                });
                //2.回显当前预约所选的套餐
                axios.get("/localOrder/findSetmealId.do?id="+row.id).then((resp)=>{
                    if (resp.data.flag) {
                        this.setmealId = resp.data.data;
                    } else {
                        this.$message.error(resp.data.message);
                    }
                });
            }
        }
    })
</script>

2.2table+复选框

目标效果:

前端页面:

<el-table :data="tableData" style="width: 100%" >
    <!--复选-->
    <el-table-column type="index" label="单选" align="center" width="80px">
        <template slot-scope="scope">
            <!--绑定setmealIds数组-->
            <el-checkbox v-model="setmealIds" :label="scope.row.id" @change="changeRedio($event,scope.row)">&nbsp;</el-checkbox>
        </template>
    </el-table-column>

    <el-table-column prop="name" label="套餐名称" width=150px></el-table-column>
    <el-table-column prop="sex" label="适用人群" width=100px align="center">
        <template slot-scope="scope">
            <span v-if="scope.row.sex==0">不限</span>
            <span v-if="scope.row.sex==1">男</span>
            <span v-if="scope.row.sex==2">女</span>
        </template>
    </el-table-column>
    <el-table-column prop="remark" label="套餐介绍" width=300px></el-table-column>
</el-table>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            tableData:[],//添加套餐数据
            setmealIds:[],//复选框对应id
            //setmealId:'',//单选框对应id
        },
        methods: {
            //回显数据
            handleUpdate(row) {
                //1.回显所有套餐信息
                axios.get("/setmeal/findAll.do").then((resp)=>{
                    if (resp.data.flag) {
                        this.tableData=resp.data.data;
                    } else {
                        this.$message.error(resp.data.message);
                        return false;
                    }
                });
                //2.回显当前预约所选的套餐
                axios.get("/localOrder/findSetmealIds.do?id="+row.id).then((resp)=>{
                    if (resp.data.flag) {
                        this.setmealIds = resp.data.data;
                    } else {
                        this.$message.error(resp.data.message);
                    }
                });
            }
        }
    })
</script>

3.分页查询

目标效果:

前端页面:

<!--1.查询按钮-->
<div class="filter-container">
    <el-input placeholder="项目编码/项目名称" v-model="pagination.queryString" style="width: 200px;" class="filter-item"></el-input>
    <el-button @click="_findPage()" class="dalfBut">查询</el-button>
    <el-button type="primary" class="butT" @click="handleCreate()">新建</el-button>
</div>
<!--2.表格-->
<el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>
    <el-table-column type="index" align="center" label="序号"></el-table-column>
    <el-table-column prop="code" label="项目编码" align="center"></el-table-column>
    <el-table-column prop="name" label="项目名称" align="center"></el-table-column>
    <el-table-column label="适用性别" align="center">
        <template slot-scope="scope">
            <span>{{ scope.row.sex == '0' ? '不限' : scope.row.sex == '1' ? '男' : '女'}}</span>
        </template>
    </el-table-column>
    <el-table-column prop="age" label="适用年龄" align="center"></el-table-column>
    <el-table-column prop="remark" label="项目说明" align="center"></el-table-column>
    <el-table-column label="操作" align="center">
        <template slot-scope="scope">
            <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑</el-button>
            <el-button size="mini" type="danger" @click="handleDelete(scope.row)">删除</el-button>
        </template>
    </el-table-column>
</el-table>
<!--3.分页栏-->
<div class="pagination-container">
    <el-pagination
                   class="pagiantion"
                   @current-change="handleCurrentChange"
                   :current-page="pagination.currentPage"
                   :page-size="pagination.pageSize"
                   layout="total, prev, pager, next, jumper"
                   :total="pagination.total">
    </el-pagination>
</div>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            pagination: {//分页相关模型数据
                currentPage: 1,//当前页码
                pageSize:10,//每页显示的记录数
                total:0,//总记录数
                queryString:null//查询条件
            },
            dataList: [],//当前页要展示的分页列表数据
        },
        //钩子函数,VUE对象初始化完成后自动执行
        created() {
            this.findPage();
        },
        methods: {
            //分页查询
            findPage() {
                //拼装请求参数对象:{currentPage:"",pageSize:"",queryString:""}
                var param = {
                    currentPage:this.pagination.currentPage,//当前页
                    pageSize:this.pagination.pageSize,//每页显示几条记录
                    queryString:this.pagination.queryString//查询条件
                }
                axios.post("/checkitem/findPage.do",param).then((resp)=>{
                    //将查询到的数据渲染到页面上
                    this.pagination.total = resp.data.total;
                    this.dataList = resp.data.rows;
                }).catch((resp)=>{
                    this.showMessage(resp);
                });
            },
            //防止在后面的分页里查询不到前面分页的记录
            _findPage() {
                //设置页码为第一页
                this.pagination.currentPage = 1;
                this.findPage();
            },
            //切换页码
            handleCurrentChange(currentPage) {
                this.pagination.currentPage = currentPage;
                this.findPage();
            },
            // 删除
            handleDelete(row) {
                //确认按钮
                this.$confirm("您确定要删除当前数据吗?","提示",{
                    type: "warning"
                }).then(()=>{
                    // alert("用户点击了确定按钮")
                    axios.get("/checkitem/delete.do?id=" + row.id).then((resp)=>{
                        if(resp.data.flag) {
                            this.$message({
                                message:resp.data.message,
                                type:"success"
                            });
                            this.findPage();
                        } else {
                            this.$message.error(resp.data.message);
                        }
                    }).catch((resp)=>{
                        this.showMessage(resp);
                    });
                }).catch(()=>{
                    // alert("用户点击了取消按钮")
                    this.$message("操作已取消");
                })
            },
            //权限不足提示
            showMessage(resp){
                if(resp == 'Error: Request failed with status code 403'){
                    //权限不足
                    this.$message.error('无访问权限');
                    return;
                }else{
                    this.$message.error('未知错误');
                    return;
                }
            }
        }
    })
</script>

4.切换按钮

目标效果:

前端页面:

<el-table size="small" current-row-key="id" :data="dataList" stripe highlight-current-row>
    <el-table-column type="index" align="center" label="序号"></el-table-column>
    <el-table-column prop="name" label="会员姓名" align="center"></el-table-column>
    <el-table-column prop="fileNumber" label="会员档案号" align="center"></el-table-column>
    <el-table-column prop="phoneNumber" label="会员手机号" align="center"></el-table-column>
    <el-table-column prop="setmealName" label="套餐名称" align="center"></el-table-column>
    <el-table-column prop="orderType" label="预约类型" align="center"></el-table-column>
    
    <!--切换预约状态-->
    <el-table-column prop="orderStatus" label="预约状态" align="center" width="200px">
        <template slot-scope="scope">
            <el-switch
                       active-text="已到诊"
                       inactive-text="未到诊"
                       v-model="scope.row.orderStatus === '已到诊'"
                       active-color="#13ce66"
                       inactive-color="#ff4949"
                       @change="orderStatusSwitch(scope.row)">
            </el-switch>
        </template>
    </el-table-column>
    
    <el-table-column prop="orderDate" label="预约日期" align="center"></el-table-column>
    <el-table-column prop="addressName" label="预约地址" align="center"></el-table-column>
    <el-table-column label="预约操作" align="center" width="200px">
        <template slot-scope="scope">
            <el-button type="primary" size="mini" @click="handleUpdate(scope.row)">编辑预约</el-button>
            <el-button size="mini" type="danger" @click="handleDelete(scope.row)">取消预约</el-button>
        </template>
    </el-table-column>
</el-table>
</div>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            dataList: [],//当前页要展示的分页列表数据
        },
        methods: {
            //切换预约状态
            orderStatusSwitch(row){
                var switchStatus = row.orderStatus === '未到诊' ? '已到诊' : '未到诊' ;
                axios.post("/localOrder/orderStatusSwitch.do",{"id":row.id,"orderStatus":switchStatus}).then((resp)=>{
                    if(resp.data.flag) {
                        this.$message({
                            type:'success',
                            message:resp.data.message
                        })
                    }
                }).catch((resp)=>{
                    this.showMessage(resp);
                }).finally(()=>{
                    this.findPage();
                })
            },
            showMessage(r){
                if(r == 'Error: Request failed with status code 403'){
                    //权限不足
                    this.$message.error('无访问权限');
                    return;
                }else{
                    this.$message.error('未知错误');
                    return;
                }
            }
        }
    })
</script>

5.动态创建下拉框

目标效果:

前端页面:

<el-select
           v-model="formData.healthManagerName"
           placeholder="请选择姓名"
           maxlength="100"
           clearable>
    <el-option
               v-for="item in healthManagerNames"
               :label="item"
               :value="item">
    </el-option>
</el-select>
<script>
	var vue = new Vue({
        el: '#app',
        data:{
            formData: {},//表单数据
            healthManagerNames:['张三','李四'],//存放所有的健康管理师姓名
        },
        methods:{
            
        }
    })
</script>

6.表单校验

以校验电话号码格式为例。

目标效果:

html页面:

<!--添加窗口-->
<div class="add-form">
    <el-dialog title="新增会员" :visible.sync="dialogFormVisible">
        <!--1.表单使用校验规则【:rules="rules"】-->
        <el-form ref="dataAddForm" :model="formData" :rules="rules" label-position="right" label-width="100px">
            <el-row>
                <el-col :span="12">
                    <!--2.在选项中定义prop属性-->
                    <el-form-item label="手机号" prop="phoneNumber">
                        <el-input v-model="formData.phoneNumber"/>
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="身份证号" prop="idCard">
                        <el-input v-model="formData.idCard"/>
                    </el-form-item>
                </el-col>
            </el-row>

            <el-row>
            </el-row>
        </el-form>
        <div slot="footer" class="dialog-footer">
            <el-button @click="dialogFormVisible = false">取消</el-button>
            <el-button type="primary" @click="handleAdd()">确定</el-button>
        </div>
    </el-dialog>
</div>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<!--3.自定义校验方法-->
<script>
    //手机号校验全局方法
    var  validatorPhone = function(rule, value, callback) {
        if (!value) {
            callback(new Error('手机号不能为空'))
        } else if (!/^1\d{10}$/.test(value)) {
            callback(new Error('请输入正确的11位手机号码'))
        } else {
            callback()
        }
    };
    //身份证号校验全局方法
    var validatorIdCard = function(rule, value, callback) {
        if (!value) {
            callback(new Error('身份证号码不能为空!'))
        } else if (!/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(value)) {
            callback(new Error('身份证号码格式错误!'))
        } else {
            callback()
        }
    };
</script>
<script>
    var vue = new Vue({
        el: '#app',
        data:{
            formData: {},//表单数据
            //4.定义校验规则,调用校验方法
            rules: {
                name: [{ required: true, message: '姓名为必填项', trigger: 'blur' }],
                phoneNumber:[{ required: true, validator: validatorPhone, trigger: 'blur'}],
                idCard:[{ required: true, validator: validatorIdCard, trigger: 'blur'}],
            }
        },
        methods: {
            //添加
            handleAdd () {
                //5.发送请求时进行表单验证
                this.$refs['dataAddForm'].validate((valid)=>{
                    // alert(valid);//true  false
                    //如果表单校验通过,发送ajax请求,将录入的表单数据提交到后台进行处理
                    if(valid){
                        axios.post('/member/add.do',this.formData).then((resp)=>{
                            //关闭窗口
                            this.dialogFormVisible = false;
                            if(resp.data.flag) {//请求执行成功
                                //执行分页查询
                                this.findPage();
                                //弹出成功提示窗口
                                this.$message({
                                    message:resp.data.message,
                                    type:'success'
                                })
                            } else {//请求执行失败
                                //弹出失败提示窗口
                                this.$message.error(resp.data.message);
                            }
                        });
                    } else {
                        //如果不通过,弹出提示框
                        this.$message.error('表单数据校验失败,请检查你的输入信息是否正确!');
                        return false;
                    }
                });
            },
        }
    })
</script>

7.动态展示菜单

7.1目标效果

给不同权限用户展示不同菜单

7.2表设计

mysql> select * from t_menu limit 0,8
;
+----+----------+-----------------------+------+----------+------------+-------------+--------------+-------+
| id | name     | linkUrl               | path | priority | icon       | description | parentMenuId | level |
+----+----------+-----------------------+------+----------+------------+-------------+--------------+-------+
|  1 | 会员管理 | NULL                  | 2    |        1 | fa-user-md | NULL        | NULL         |     1 |
|  2 | 会员档案 | member.html           | /2-1 |        1 | NULL       | NULL        |            1 |     2 |
|  3 | 体检上传 | NULL                  | /2-2 |        2 | NULL       | NULL        |            1 |     2 |
|  4 | 会员统计 | NULL                  | /2-3 |        3 | NULL       | NULL        |            1 |     2 |
|  5 | 预约管理 | NULL                  | 3    |        2 | fa-tty     | NULL        | NULL         |     1 |
|  6 | 预约列表 | ordersettinglist.html | /3-1 |        1 | NULL       | NULL        |            5 |     2 |
|  7 | 预约设置 | ordersetting.html     | /3-2 |        2 | NULL       | NULL        |            5 |     2 |
|  8 | 套餐管理 | setmeal.html          | /3-3 |        3 | NULL       | NULL        |            5 |     2 |
+----+----------+-----------------------+------+----------+------------+-------------+--------------+-------+
8 rows in set

7.2前端页面

<el-container>
    <!--左侧菜单栏-->
    <el-aside width="200px">
        <el-menu>
            <el-submenu v-for="menu in menuList" :index="menu.path">
                <template slot="title">
                    <i class="fa" :class="menu.icon"></i>
                    {{menu.title}}
                </template>
                <template v-for="child in menu.children">
                    <el-menu-item :index="child.path">
                        <a :href="child.linkUrl" target="right">{{child.title}}</a>
                    </el-menu-item>
                </template>
            </el-submenu>
        </el-menu>
    </el-aside>
    <!--右侧展示页面-->
    <el-container>
        <iframe name="right" class="el-main" src="ordersetting.html" width="100%" height="580px" frameborder="0"></iframe>
    </el-container>
</el-container>
<!-- 引入组件库 -->
<script src="../js/vue.js"></script>
<script src="../plugins/elementui/index.js"></script>
<script type="text/javascript" src="../js/jquery.min.js"></script>
<script src="../js/axios-0.18.0.js"></script>
<script>
    new Vue({
        el: '#app',
        data:{
            username:"TSCCG",//当前登录用户的用户名
            menuList:[]//菜单数据
        },
        created(){
            //发送ajax请求,向Controller请求获取当前登录用户的用户名,展示到页面上
            axios.get("/user/getUsername.do").then((resp)=>{
                if(resp.data.flag) {
                    this.username = resp.data.data;
                    //发送ajax请求,根据当前用户名向Controller请求可查看的菜单
                    axios.get("/menu/findMenuListByUserName.do?username="+this.username).then((resp)=>{
                        if (resp.data.flag){
                            this.menuList = resp.data.data;
                        } else {
                            this.$message.error(resp);
                        }
                    });
                }
            })
        }
    });
    $(function() {
        var wd = 200;
        $(".el-main").css('width', $('body').width() - wd + 'px');
    });
</script>

7.3前端所需数据

[
    {
        "path": "1",
        "title": "工作台",
        "icon":"fa-dashboard",
        "children": []
    },
    {
        "path": "2",
        "title": "会员管理",
        "icon":"fa-user-md",
        "children": [
            {
                "path": "/2-1",
                "title": "会员档案",
                "linkUrl":"member.html",
            },
            {
                "path": "/2-2",
                "title": "体检上传",
                "linkUrl":""
            }
        ]
    }
    ...
]

7.4后端代码

7.4.1Controller

@RestController
@RequestMapping("/menu")
public class MenuController {
    @Reference
    private MenuService menuService;

    /**
     * 根据当前用户名获取对应的菜单列表
     * @param username 当前用户名
     * @return 菜单列表,json数组
     */
    @RequestMapping("/findMenuListByUserName")
    public Result findMenuListByUserName(String username) {
        try {
            List<Map<String,Object>> menuList = menuService.findMenuListByUserName(username);
            return new Result(true, MessageConstant.QUERY_MENU_LIST_SUCCESS,menuList);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, MessageConstant.QUERY_MENU_LIST_FAIL);
        }
    }
}

7.4.2Service

接口:

public interface MenuService {

    /**
     * 根据当前用户名获取对应的菜单列表
     * @param username 当前用户名
     * @return 菜单列表,json数组
     */
    List<Map<String, Object>> findMenuListByUserName(String username);
}

实现类:

@Service(interfaceClass = MenuService.class)
@Transactional
public class MenuServiceImpl implements MenuService{
    @Autowired
    private MenuDao menuDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private UserDao userDao;
    /**
     * 根据当前用户名获取对应的菜单列表
     * @param username 当前用户名
     * @return 菜单列表,json数组
     *  [
     *     {
     *         "path": "1",
     *         "title": "工作台",
     *         "icon":"fa-dashboard",
     *         "children": []
     *     },
     *     {
     *         "path": "2",
     *         "title": "会员管理",
     *         "icon":"fa-user-md",
     *         "children": [
     *             {
     *                 "path": "/2-1",
     *                 "title": "会员档案",
     *                 "linkUrl":"member.html",
     *             },
     *             {
     *                 "path": "/2-2",
     *                 "title": "体检上传",
     *                 "linkUrl":""
     *             }
     *         ]
     *     }
     * ]
     */
    @Override
    public List<Map<String, Object>> findMenuListByUserName(String username) {
        //定义存放菜单列表的集合
        List<Map<String,Object>> menuMapList = new ArrayList<>();
        //1.根据用户名查询用户基本信息(不包括关联的角色)
        User user = userDao.findByName(username);
        if (user == null) {
            return null;
        }
        //2.根据上一步查出的用户id查询关联的所有角色
        Set<Role> roles = roleDao.findByUserId(user.getId());
        if (roles != null && roles.size() > 0) {
            //遍历角色集合
            for (Role role : roles) {
                //3.根据当前角色id查询关联的顶级菜单列表
                List<Menu> parentMenuList = menuDao.findParentMenuByRoleId(role.getId());
                if (parentMenuList != null && parentMenuList.size() > 0) {
                    //遍历顶级菜单集合
                    for (Menu parentMenu : parentMenuList) {
                        //4.将顶级菜单数据封装到一个map中
                        Map<String, Object> parentMap = new HashMap<>();
                        parentMap.put("path", parentMenu.getPath());
                        parentMap.put("title", parentMenu.getName());
                        parentMap.put("icon", parentMenu.getIcon());
                        //5.根据顶级菜单id查询对应的子菜单列表
                        List<Menu> childrenMenuList = menuDao.findChildrenMenuByParentId(parentMenu.getId());
                        if (childrenMenuList != null && childrenMenuList.size() > 0) {
                            //6.遍历子菜单列表,将所有子菜单数据封装到一个List集合中
                            List<Map<String, Object>> childMapList = new ArrayList<>();
                            for (Menu childMenu : childrenMenuList) {
                                //将当前子菜单数据封装到一个map中
                                Map<String, Object> childMap = new HashMap<>();
                                childMap.put("path", childMenu.getPath());
                                childMap.put("title", childMenu.getName());
                                childMap.put("linkUrl", childMenu.getLinkUrl());
                                //将map添加到childMapList中
                                childMapList.add(childMap);
                            }
                            parentMap.put("children", childMapList);
                        }
                        //6.将顶级菜单Map集合添加到总List集合中
                        menuMapList.add(parentMap);
                    }
                }
            }
        }
        //7.返回装有所有菜单数据的list集合
        return menuMapList;
    }
}

7.4.3Dao

接口:

public interface MenuDao {
    /**
     * 根据角色id查询关联的顶级菜单列表
     * @param roleId
     * @return
     */
    List<Menu> findParentMenuByRoleId(Integer roleId);

    /**
     * 根据顶级菜单Id查询对应的子菜单列表
     * @param parentId
     * @return
     */
    List<Menu> findChildrenMenuByParentId(Integer parentId);
}

mapper映射文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.tsccg.dao.MenuDao">
    <!--根据角色id查询关联的顶级菜单列表-->
    <select id="findParentMenuByRoleId" parameterType="int" resultType="com.tsccg.pojo.Menu">
        select m.*
        from t_role_menu rm
        join t_menu m
        on rm.menu_id = m.id
        where rm.role_id = #{role_id} and parentMenuId is null
    </select>
    <!--根据顶级菜单Id查询对应的子菜单列表-->
    <select id="findChildrenMenuByParentId" parameterType="int" resultType="com.tsccg.pojo.Menu">
        select name,linkUrl,path
        from t_menu
        where parentMenuId = #{parentMenuId}
    </select>
</mapper>
posted @ 2021-12-06 18:34  TSCCG  阅读(404)  评论(0编辑  收藏  举报