一、动态路由菜单
1.动态获取菜单数据
api/user.js中添加getMenuList()方法
/**
* 获取菜单数据
*/
export async function getMenuList(){
return await http.get("/api/sysUser/getMenuList")
}
src/store/modules/permission.js
const actions = {
/**
* 动态生成路由
* @returns
*/
generateRoutes({ commit }, roles) {
return new Promise((resolve,reject) => {
getMenuList().then(res=>{
let accessedRoutes//存放对应权限的路由信息
//如果状态码为200,则表示成功
if (res.code===200) {
accessedRoutes = filterAsyncRoutes(res.data,roles);
}
//将路由信息保存到store中
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
}).catch(error=>{
reject(error)
})
})
}
}
2.生成动态路由
src/views下创建系统模块的文件夹及页面
store/modules/premission.js
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
//判断是否有相应的权限
if (hasPermission(roles, tmp)) {
//获取组件
const component=tmp.component;
//判断该路由使用有组件
if (route.component) {
//判断是否有根组件
if(component==='Layout'){
tmp.component = Layout
}else{
//获取对应的具体的组件信息
tmp.component=(resolve)=>require([`@/views${component}`],reslove)
}
//判断是否有子菜单
if(tmp.children){
tmp.children=filterAsyncRoutes(tmp.children,roles)
}
}
res.push(tmp)
}
})
return res
}
二、部门管理模块
1.查询部门列表
src/views/system/department/department.vue
<template>
<el-main>
<!-- 查询条件 -->
<el-form
ref="searchForm"
label-width="80px"
:inline="true"
size="small"
>
<el-form-item>
<el-input palceholder="请输入部门名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search">查询</el-button>
<el-button icon="el-icon-refresh-right">重置</el-button>
<el-button type="success" icon="el-icon-plus">新增</el-button>
</el-form-item>
</el-form>
<!-- 数据表格 -->
<el-table
:data="tableData"
border
stripe
style="width:100px; margin-bottom:20px"
row-key="id"
default-expand-all
:tree-props="{children:'children'}"
>
<el-table-column prop ="name" label="部门名称"></el-table-column>
<el-table-column prop ="parentName" label="所属部门"></el-table-column>
<el-table-column prop ="deptCode" label="部门编码"></el-table-column>
<el-table-column prop ="depPhone" label="部门电话"></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
icon="el-icon-edit-outline"
type="primary"
size="small"
@click="handleEdit(scope.row)"
>编辑
</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</template>
<script>
export default {
name:'department',
data(){
return{
tableDate:[]//表格数据列表
}
},
methods:{
/**
* 编辑部门
* @param row
*/
handleEdit(row){
},
/**
* 删除部门
* @param row
*/
handleDelete(row){
}
},
created(){
}
}
</script>
<style lang="scss" scoped >
</style>
src/api目录下创建department.js脚本文件
import http from '@utils/request';
export default{
/**
* 查询部门列表
* @param param
* @returns
*/
async getDepartmentList(param){
return await http.get("/api/department/list",param)
}
}
src/views/system/department/department.vue
<template>
<el-main>
<!-- 查询条件 -->
<el-form :model="searchModel" ref="searchForm" label-width="80px"
:inline="true" size="small">
<el-form-item>
<el-input palceholder="请输入部门名称" v-model="searchModel.departmentName"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
<el-button icon="el-icon-refresh-right" @click="resetValue()">重置</el-button>
<el-button type="success" icon="el-icon-plus">新增</el-button>
</el-form-item>
</el-form>
<!-- 数据表格 -->
<!--
data:表格数据
border属性:表格边框
stripe:表格斑马线
row-key:行数据的key,用来优化Table的渲染
default-expand-all默认展开树形表格数据
tree-props:树形表格配置属性选型
-->
<el-table
:data="tableData"
border
stripe
style="width:100%; margin-bottom:20px"
row-key="id"
default-expand-all
:tree-props="{children:'children'}"
>
<!-- prop:填写数据的属性名称 -->
<!-- label:表格表头标题 -->
<el-table-column prop ="name" label="部门名称"></el-table-column>
<el-table-column prop ="parentName" label="所属部门"></el-table-column>
<el-table-column prop ="depPhone" label="部门电话"></el-table-column>
<el-table-column prop ="address" label="部门位置"></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
icon="el-icon-edit-outline"
type="primary"
size="small"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
icon="el-icon-close"
type="danger"
size="small"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
</el-main>
</template>
<script>
import departmentApi from "@/api/department";
export default {
name:'department',
data(){
return{
searchModel:{
departmentName:""//部门名称
},
tableDate:[]//表格数据列表
}
},
methods:{
/**
* 查询部门列表
* @param row
*/
async search(){
//发送查询请求
let res =await departmentApi.getDepartmentList(this.searchmodel);
//判断是否存在数据
if(res.success){
//获取数据
this.tableDate=res.data;
}
},
/**
* 重置
*/
resetValue(){
this.searchModel={};//清空数据
this.search();//重新调用方法
}
},
// handleEdit(row){
// },
// /**
// * 删除部门
// * @param row
// */
// handleDelete(row){
// }
// },
//初始化时执行
created(){
//调用查询部门列表方法
this.search();
}
};
</script>
<style lang="scss" scoped >
</style>
2.新增部门
src/components下创建system目录,并且在system目录下创建SystemDialog.vue组件
<template>
<div>
<el-dialog
top="5vh"
:title="title"
:visible.sync="visible"
:width="width+'px'"
:before-close="onClose"
:close-on-click-modal="false"
>
<div class ="container" :style="{height:height+'px'}">
<slot name="content>"></slot>
</div>
<span slot="footer" class="dialong-footer">
<el-button @click="onClose">取 消</el-button>
<el-button type="primary" @click="conConfirm">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
props:{
title:{
type:String,
default:"标题",
},
visible:{
type:Boolean,
default:false,
},
width:{
type:Number,
default:250,
},
},
data(){
return{}
},
methods:{
onClose(){
this.$emit("onClose");
},
onConfirm(){
this.$emit("onConfirm");
}
}
}
</script>
<style lang="scss" scoped>
.container{
overflow-x:initial;
overflow-y:auto;
}
.el-dialog__wrapper{
::v-deep .eldialog{
border-top-left-radius:7px !important;
border-top-right-radius:7px !important;
.el-dialog__header{
border-top-left-radius:7px !important;
border-top-right-radius:7px !important;
background-color: #1890ff;
.el-dialog__title{
color:#fff;
font-size:15px;
font-weight:700;
}
.el-dialog__close{
color:#fff;
}
}
.el-dialog__body{
padding:10 px 10px !important;
}
.el-dialog__footer{
border-top:1px solid #e8eaec !important;
padding:10px !important;
}
}
}
</style>
src/views/system/department/department.vue
<template>
<el-main>
<!-- 查询条件 -->
<el-form :model="searchModel" ref="searchForm" label-width="80px"
:inline="true" size="small">
<el-form-item>
<el-input palceholder="请输入部门名称" v-model="searchModel.departmentName"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
<el-button icon="el-icon-refresh-right" @click="resetValue()">重置</el-button>
<el-button type="success" icon="el-icon-plus">新增</el-button>
</el-form-item>
</el-form>
<!-- 数据表格 -->
<!--
data:表格数据
border属性:表格边框
stripe:表格斑马线
row-key:行数据的key,用来优化Table的渲染
default-expand-all默认展开树形表格数据
tree-props:树形表格配置属性选型
-->
<el-table
:data="tableData"
border
stripe
style="width:100%; margin-bottom:20px"
row-key="id"
default-expand-all
:tree-props="{children:'children'}"
>
<!-- prop:填写数据的属性名称 -->
<!-- label:表格表头标题 -->
<el-table-column prop ="name" label="部门名称"></el-table-column>
<el-table-column prop ="parentName" label="所属部门"></el-table-column>
<el-table-column prop ="depPhone" label="部门电话"></el-table-column>
<el-table-column prop ="address" label="部门位置"></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
icon="el-icon-edit-outline"
type="primary"
size="small"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
icon="el-icon-close"
type="danger"
size="small"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加和编辑部门窗口 -->
<system-dialog
:title="deptDialog.title"
:visible="deptDialog.visible"
:width="deptDialog.width"
:height="deptDialog.height"
@onClose="onClose"
@onConfirm="onConfirm"
>
<div slot="content">
<el-form
:model="dept"
ref="deptFrom"
:rules="rules"
label-width="80px"
:inline="true"
size="small"
>
<el-form-item label="所属部门" prop="parentName">
<el-input
v-model="dept.parentName"
@click.native="selectDepartment()"
:readonly="true"
></el-input>
</el-form-item>
<el-form-item label="部门名称" prop="departmentName">
<el-input v-model="dept.deparmentName"></el-input>
</el-form-item>
<el-form-item label="部门电话" >
<el-input v-model="dept.phone"></el-input>
</el-form-item>
<el-form-item label="部门地址" >
<el-input v-model="dept.address"></el-input>
</el-form-item>
<el-form-item label="序号" >
<el-input v-model="dept.orderNum"></el-input>
</el-form-item>
</el-form>
</div>
</system-dialog>
</el-main>
</template>
<script>
import departmentApi from "@/api/department";
//导入对话框组件
import SystemDialog from '@/components/system/SystemDialog.vue'
export default {
name:'department',
//注册组件
components:{
SystemDialog
},
data(){
return{
searchModel:{
departmentName:""//部门名称
},
tableDate:[],//表格数据列表
deptDialog:{
title:"",//窗口标题
visible:false,//是否显示窗口
width:560,//窗口宽度
height:170//窗口高度
},
//部门对象
dept:{
id:"",
pid:"",//所属部门id
parentName:"",//所属部门名称
address:"",//地址
phone:"",//电弧
orderNum:"",//序号
},
//表单验证规则
rules:{
parentName:[{required:true, tigger:"change", message:"请选择所属部门"}],
departmnet:[{required:true, tigger:"blur", message:"请输入部门名称"}],
}
}
},
//初始化时调用
created(){
//调用查询部门列表
this.search();
},
methods:{
/**
* 查询部门列表
* @param row
*/
async search(){
//发送查询请求
let res =await departmentApi.getDepartmentList(this.searchmodel);
//判断是否存在数据
if(res.success){
//获取数据
this.tableDate=res.data;
}
},
/**
* 弹窗取消事件
*/
onClose(){
//关闭窗口
thise.deptDialog.visible=false;
},
/**
* 弹窗确定事件
*/
onConfirm(){
//表单验证
this.$refs.deptForm.validate((valid)=>{
//如果验证通过
if(valid){
//关闭窗口
this.deptDialog.visible=false;
}
})
},
/**
* 打开添加部门窗口
*/
openAddWindow(){
//设置窗口标题
this.deptDialog.title="新增部门"
//显示添加部门窗口
this.deptDialog.visible=true
},
/**
* 选择所属部门
*/
selctDepartment(){},
}
};
</script>
<style lang="scss" scoped >
</style>
编写选择所属部门代码
src/api/department.js
/**
* 获取所属部门列表
*/
async getParentTreeList(){
return await http.get("/api/department/parent/list")
}
src/views/system/department/department.vue
<template>
<el-main>
<!-- 查询条件 -->
<el-form :model="searchModel" ref="searchForm" label-width="80px"
:inline="true" size="small">
<el-form-item>
<el-input palceholder="请输入部门名称" v-model="searchModel.departmentName"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="search()">查询</el-button>
<el-button icon="el-icon-refresh-right" @click="resetValue()">重置</el-button>
<el-button type="success" icon="el-icon-plus" @click="openAddWindow()">新增</el-button>
</el-form-item>
</el-form>
<!-- 数据表格 -->
<!--
data:表格数据
border属性:表格边框
stripe:表格斑马线
row-key:行数据的key,用来优化Table的渲染
default-expand-all默认展开树形表格数据
tree-props:树形表格配置属性选型
-->
<el-table
:data="tableData"
border
stripe
style="width:100%; margin-bottom:20px"
row-key="id"
default-expand-all
:tree-props="{children:'children'}"
>
<!-- prop:填写数据的属性名称 -->
<!-- label:表格表头标题 -->
<el-table-column prop ="name" label="部门名称"></el-table-column>
<el-table-column prop ="parentName" label="所属部门"></el-table-column>
<el-table-column prop ="depPhone" label="部门电话"></el-table-column>
<el-table-column prop ="address" label="部门位置"></el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
icon="el-icon-edit-outline"
type="primary"
size="small"
@click="handleEdit(scope.row)"
>编辑
</el-button>
<el-button
icon="el-icon-close"
type="danger"
size="small"
@click="handleDelete(scope.row)"
>删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加和编辑部门窗口 -->
<system-dialog
:title="deptDialog.title"
:visible="deptDialog.visible"
:width="deptDialog.width"
:height="deptDialog.height"
@onClose="onClose"
@onConfirm="onConfirm">
<div slot="content">
<el-form
:model="dept"
ref="deptFrom"
:rules="rules"
label-width="80px"
:inline="true"
size="small"
>
<el-form-item label="所属部门" prop="parentName">
<el-input
v-model="dept.parentName"
@click.native="openSelectDepartment()"
:readonly="true"
></el-input>
</el-form-item>
<el-form-item label="部门名称" prop="departmentName">
<el-input v-model="dept.deparmentName"></el-input>
</el-form-item>
<el-form-item label="部门电话" >
<el-input v-model="dept.phone"></el-input>
</el-form-item>
<el-form-item label="部门地址" >
<el-input v-model="dept.address"></el-input>
</el-form-item>
<el-form-item label="序号" >
<el-input v-model="dept.orderNum"></el-input>
</el-form-item>
</el-form>
</div>
</system-dialog>
<!-- 选择所属部门的窗口 -->
<system-dialog
:title="parentDialog.title"
:visible="parentDialog.visible"
:width="parentDialog.width"
:height="parentDialog.height"
@onClose="parentOnClose()"
@onConfirm="parentOnConfirm()">
<div slot="content">
<el-tree
ref="parentTree"
:data="treeList"
node-key="id"
:props="defaultProps"
:default-expand-all="true"
:highlight-current="true"
:expand-on-click-node="false"
@node-click="handleNodeClick"
>
<div class="custome-tree-node" slot-scope="{node,data}">
<!-- 判断当前节点的子节点长度是否为0 -->
<span v-if="data.childrren.length===0">
<i class="el-icon-document"></i>
</span>
<span v-else>
<svg-icon v-if="data.open" icon-class="add-s"></svg-icon>
<svg-icon v-else icon-class="sub-s"></svg-icon>
</span>
<span style="margin-left:3px">{{node.label}}</span>
</div>
</el-tree>
</div>
</system-dialog>
</el-main>
</template>
<script>
import departmentApi from "@/api/department";
//导入对话框组件
import SystemDialog from '@/components/system/SystemDialog.vue'
export default {
name:'department',
//注册组件
components:{
SystemDialog
},
data(){
return{
searchModel:{
departmentName:""//部门名称
},
tableDate:[],//表格数据列表
deptDialog:{
title:"",//窗口标题
visible:false,//是否显示窗口
width:560,//窗口宽度
height:170//窗口高度
},
//部门对象
dept:{
id:"",
departmentName:"",
pid:"",//所属部门id
parentName:"",//所属部门名称
address:"",//地址
phone:"",//电弧
orderNum:"",//序号
},
//表单验证规则
rules:{
parentName:[{required:true, tigger:"change", message:"请选择所属部门"}],
departmnet:[{required:true, tigger:"blur", message:"请输入部门名称"}],
},
//选择所属部门窗口属性
parentDialog:{
title:"选择部门",
visible:false,
width:300,
height:400,
},
treeList:[],//树形数据
//树形组件默认属性值
defaultProps:{
children:'children',
label:'departmentName'
}
};
},
//初始化时调用
created(){
//调用查询部门列表
this.search();
},
methods:{
/**
* 查询部门列表
* @param row
*/
async search(){
//发送查询请求
let res =await departmentApi.getDepartmentList(this.searchmodel);
//判断是否存在数据
if(res.success){
//获取数据
this.tableDate=res.data;
}
},
/**
* 弹窗取消事件
*/
onClose(){
//关闭窗口
thise.deptDialog.visible=false;
},
/**
* 弹窗确定事件
*/
onConfirm(){
//表单验证
this.$refs.deptForm.validate((valid)=>{
//如果验证通过
if(valid){
//关闭窗口
this.deptDialog.visible=false;
}
})
},
/**
* 选择所属部门取消事件
*/
onParentClose(){
this.parentDialog.visible=false;
},
/**
* 选择所属部门确定事件
*/
onParentConfirm(){
this.parentDialog.visible=false;
},
/**
* 打开添加部门窗口
*/
openAddWindow(){
//设置窗口标题
this.deptDialog.title="新增部门"
//显示添加部门窗口
this.deptDialog.visible=true
},
/**
* 打开选择所属部门
*/
async openSelectDepartment(){
//设置窗口属性
this.parentDialog.visible=true;
//查询所属部门列表
let res = await departmentApi.getParentTreeList();
//判断是否成功
if(res.success){
this.treeList=res.data;
}
},
/**
* 点击树节点加减号时触发
*/
changeicon(data){
//修改折叠状态
data.open=!data.open;
this.$refs.parentTree.store.nodesMap[data.id].expanded-!data.open;
},
/**
* 树节点点击事件
*/
handleNodeClick(data){
//将选中的部门赋值给dept对象
this.dept.id=data.id;
this.dept.parentName=data.departmentName;
},
}
};
</script>
<style lang="scss" scoped >
::v-deep .el-tree{
.el-tree-node{
position:relative;
padding-left:10px;
}
.el-tree-node__children{
padding-left:20px;
}
.el-tree-node:last-child:before{
height:40px;
}
.el-tree> .el-tree-node:after{
border-top:none;
}
.el-tree-node:before,
.el-tree-node:after{
content:"";
left: -4px;
position:absolute;
right:auto;
border-width:1px;
}
.tree :first-children .el-tree-node:before{
border-left:none;
}
.el-tree-node:before{
border-left:1px dotted #d9d9d9;
bottom:0px;
height:100%;
top:-25px;
width:1px;
}
.el-tree-node:after{
border-top:1px dotted #d9d9d9;
height:20px;
top:14px;
width:24px;
}
.el-tree-node__expand-icon.is-leaf{
width:8px;
}
.el-tree-node__content{
line-height:30px;
height:30px;
padding-left:1px!important;
}
}
::v-deep .el-tree > div{
&::before{
display:none;
}
&::after{
display:none;
}
}
</style>
表单数据快速清空
src/utils创建resetForm.js脚本文件
//重置表单和表单数据
export default function resetForm(fromName,obj){
//清空表单
if(this.$refs[fromName]){
this.$refs[fromName].resetFields();
}
//清空数据
Object.keys(obj).forEach(key=>{
obj[key]='';
})
}
src/main.js
//导入清空表单工具
import resetForm from '@/utils/resetForm'
Vue.prototype.$myconfirm=myconfirm;
src/views/system/department/department.vue
openAddWindow(){
//清空表单数据
this.$resetForm("deptForm",this.dept);
//设置窗口标题
this.deptDialog.title="新增部门"
//显示添加部门窗口
this.deptDialog.visible=true
},
新增部门
src/api/department.js
/**
* 添加部门
*/
async addDept(params){
return await http.post("/api/department/add",params);
}
}
src/views/system/department/department.vue
/**
* 弹窗确定事件
*/
onConfirm(){
//表单验证
this.$refs.deptForm.validate(async(valid)=>{
//如果验证通过
if(valid){
//发送添加请求
let res = await departmentApi.addDept(this.dept)
//判断是否成功
if(res.success){
//提示成功
this.$message.success(res.message);
//刷新
this.search();
//关闭窗口
this.deptDialog.visible=false;
}else{
//提示失败
this.$message.error(res.message);
}
}
})
},
8.18-8.19学习汇报与总结
1.学习体会与感受
接口测试和视频不一样,自己不会写。还是太菜了,就算知道解决方法,自己也不会写,不管怎样辗转几天的端口问题,最后总归找到笨笨的解决办法是借后端代码直接测试,由于这两天没有端口测试,估计后面改bug问题不小,希望自己导入后端文件顺利,能快点开始联调找问题。
2.8.20-8.21学习计划
完成后端文件导入进行测试,抓紧完成前端部分代码交给后端测试接口。