1.0 全模块集成

目标: 将其他业务模块代码集成到该项目中

到目前为止,我们已经完成了一个基本项目框架 + 组织架构 + 公司 + 员工 + 权限的 业务联调, 时间关系,我们不可能将所有的业务都去编写一遍,这里提供大家 其余模块的集成代码,最终的目的是让大家得到一个完成的业务模块

要集成的模块业务,包括工资模块,社保模块,考勤模块,审批模块

在我们提供的资源集成模块中,我们提供了四个模块的**路由/页面/api*, 按照下面的路径拷贝即可

路由 => src/router/modules

页面 => src/views

api => src/api 里面差 constant 里面的文件 , 去总代码里面粘贴

除此之外,我们需要将 router/modules/user.js 导入到静态路由中,因为这个模块是所有模块都可以访问的

最终,我们将得到一个较为完整的系统业务。

里面有很多 路径都错了 需要

2.0 首页的页面结构

目标: 实现系统首页的页面结构

  1. 首页页面结构,src/views/dashboard/index.vue
<template><div class="dashboard-container"><!-- 头部内容 --><el-card class="header-card"><div><div class="fl headL"><div class="headImg"><img src="@/assets/common/head.jpg"></div><div class="headInfoTip"><p class="firstChild">早安,管理员,祝你开心每一天!</p><p class="lastChild">早安,管理员,祝你开心每一天!</p></div></div><div class="fr" /></div></el-card><!-- 主要内容 --><el-row type="flex" justify="space-between"><!-- 左侧内容 --><el-col :span="13" style="padding-right:26px"><!-- 工作日历 --><el-card class="box-card"><div slot="header" class="header"><span>工作日历</span></div><!-- 放置日历组件 --></el-card><!-- 公告 --><el-card class="box-card"><div class="advContent"><div class="title"> 公告</div><div class="contentItem"><ul class="noticeList"><li><div class="item"><img src="@/assets/common/img.jpeg" alt=""><div><p><span class="col">朱继柳</span> 发布了 第1期“传智大讲堂”互动讨论获奖名单公布</p><p>2018-07-21 15:21:38</p></div></div></li><li><div class="item"><img src="@/assets/common/img.jpeg" alt=""><div><p><span class="col">朱继柳</span> 发布了 第2期“传智大讲堂”互动讨论获奖名单公布</p><p>2018-07-21 15:21:38</p></div></div></li><li><div class="item"><img src="@/assets/common/img.jpeg" alt=""><div><p><span class="col">朱继柳</span> 发布了 第3期“传智大讲堂”互动讨论获奖名单公布</p><p>2018-07-21 15:21:38</p></div></div></li></ul></div></div></el-card></el-col><!-- 右侧内容 --><el-col :span="11"><el-card class="box-card"><div class="header headTit"><span>流程申请</span></div><div class="sideNav"><el-button class="sideBtn">加班离职</el-button><el-button class="sideBtn">请假调休</el-button><el-button class="sideBtn">审批列表</el-button><el-button class="sideBtn">我的信息</el-button></div></el-card><!-- 绩效指数 --><el-card class="box-card"><div slot="header" class="header"><span>绩效指数</span></div><!-- 放置雷达图 --></el-card><!-- 帮助连接 --><el-card class="box-card"><div class="header headTit"><span>帮助链接</span></div><div class="sideLink"><el-row><el-col :span="8"><a href="#"><span class="icon iconGuide" /><p>入门指南</p></a></el-col><el-col :span="8"><a href="#"><span class="icon iconHelp" /><p>在线帮助手册</p></a></el-col><el-col :span="8"><a href="#"><span class="icon iconTechnology" /><p>联系技术支持</p></a></el-col></el-row></div></el-card></el-col></el-row></div>
</template><script>
import { mapGetters } from 'vuex'export default {name: 'Dashboard',computed: {...mapGetters(['name'])}
}
</script><style lang="scss" scoped>
.dashboard-container {margin: 10px;li {list-style: none;}.headImg {float: left;width: 100px;height: 100px;border-radius: 50%;background: #999;img {width: 100%;height: 100%;border-radius: 50%;}}.headInfoTip {padding: 25px 0 0;margin-left: 120px;p {padding: 0 0 15px;margin: 0;&.firstChild {font-size: 24px;}&.lastChild {font-size: 20px;color: #7f8c8d;}}}
}.box-card {padding: 5px 10px;margin-top: 20px;.header {span {color: #2c3e50;font-size: 24px;}.item {color: #97a8be;float: right;padding: 3px 0;}}.headTit {span {border-bottom: 4px solid #8a97f8;padding-bottom: 10px;}}
}
.header-card{position: relative;.header {position: absolute;right: 20px;top: 15px;z-index: 1;}
}.advContent {background: #fff;border-radius: 5px 5px 0px 0px;.title {font-size: 16px;padding: 20px;font-weight: bold;border-bottom: solid 1px #ccc;}.contentItem {padding: 0 30px;min-height: 350px;.item {display: flex;padding:18px 0 10px;border-bottom: solid 1px #ccc;.col {color: #8a97f8;}img {width: 56px;height: 56px;border-radius: 50%;margin-right: 10px;}p{padding: 0 0 8px;}}}
}
.noticeList {margin: 0;padding: 0;
}
.sideNav,
.sideLink {padding: 30px 0 12px;.sideBtn {padding: 16px 26px;font-size:16px;margin: 10px 5px;}
}
.sideLink {text-align: center;.icon {display: inline-block;width: 76px;height: 76px;background: url('./../../assets/common/icon.png') no-repeat;}.iconGuide {background-position: 0 0;}.iconHelp {background-position: -224px 0;}.iconTechnology {background-position: -460px 0;}
}
</style>

3.0 首页用户资料显示

目标:将首页的信息换成真实的用户资料

直接获取Vuex的用户资料即可

<script>
import { createNamespacedHelpers } from 'vuex'
const { mapState } = createNamespacedHelpers('user')
export default {name: 'Dashboard',data() {return {defaultImg: require('@/assets/common/head.jpg'),}},computed: {...mapState(['userInfo'])}
}
</script>
  1. 在 vue视图中绑定
<div class="fl headL"><div class="headImg"><img :src="userInfo.staffPhoto"></div><div class="headInfoTip"><p class="firstChild">早安,{{ userInfo.username }},祝你开心每一天!</p><p class="lastChild">{{ userInfo.username }}   |  {{ userInfo.companyName }}-{{ userInfo.departmentName }}</p></div></div>
  1. 除此之外,当我们加载图片失败的时候,图片地址存在,但是却不能显示,之前我们封装的图片错误指令可以应用
<img  :src="userInfo.staffPhoto" v-imageerror="defaultImg">

4.0 工作日历组件封装

目标: 封装一个工作日历组件在首页中展示

4.1 新建工作日历组件结构

工作日历的要求很简单,显示每个月的日期,可以设定日期的范围

我们可以基于Element组件el-calendar进行封装(删除 /deep/ )
src/views/dashboard/components/work-calendar.vue

<template><div><el-row type="flex" justify="end"><el-select v-model="currentYear" size="small" style="width: 120px" @change="dateChange"><el-option v-for="item in yearList" :key="item" :label="item" :value="item">{{ item }}</el-option></el-select><el-select v-model="currentMonth" size="small" style="width: 120px;margin-left:10px" @change="dateChange"><el-option v-for="item in 12" :key="item" :label="item" :value="item">{{ item }}</el-option></el-select></el-row><el-calendar v-model="currentDate"><template v-slot:dateCell="{ date, data }" class="content"><div class="date-content"><span class="text"> {{ data.day | getDay }}</span><span v-if="isWeek(date)" class="rest">休</span></div> </template></el-calendar></div>
</template><script>
export default {props: {startDate: {type: Date,default: () => new Date()}},data() {return {currentMonth: null, // 当前月份currentYear: null, // 当前年份currentDate: null,yearList: []}}
}
</script><style  scoped>/deep/ .el-calendar-day {height:  auto;}/deep/ .el-calendar-table__row td,/deep/ .el-calendar-table tr td:first-child,  /deep/ .el-calendar-table__row td.prev{border:none;}
.date-content {height: 40px;text-align: center;line-height: 40px;font-size: 14px;
}
.date-content .rest {color: #fff;border-radius: 50%;background: rgb(250, 124, 77);width: 20px;height: 20px;line-height: 20px;display: inline-block;font-size: 12px;margin-left: 10px;
}
.date-content .text{width: 20px;height: 20px;line-height: 20px;display: inline-block;}/deep/ .el-calendar-table td.is-selected .text{background: #409eff;color: #fff;border-radius: 50%;}/deep/ .el-calendar__header {display: none}
</style>

4.2 实现工作日历逻辑

export default {filters: {getDay(value) {const day = value.split('-')[2]return day.startsWith('0') ? day.substr(1) : day}},props: {startDate: {type: Date,default: () => new Date()}},data() {return {currentMonth: null, // 当前月份currentYear: null, // 当前年份currentDate: null,yearList: []}},//   初始化事件created() {//    处理起始时间// 组件要求起始时间必须是 周一开始 以一个月为开始this.currentMonth = this.startDate.getMonth() + 1this.currentYear = this.startDate.getFullYear()// 根据当前的年 生成可选年份 前后各加5年this.yearList = Array.from(Array(11), (value, index) =>  this.currentYear + index - 5 )// 计算 当年当月的第一个周一 再加上 四周之后的一个月月份this.dateChange()},methods: {// 是否是休息日isWeek(value) {return value.getDay() === 6 || value.getDay() === 0},// 年月份改变之后dateChange() {const year = this.currentYearconst month = this.currentMonththis.currentDate = new Date(`${year}-${month}-1`) // 以当前月的1号为起始}}
}
  1. 在主页中应用
  <!-- 放置日历组件 --><work-calendar />

5.0封装雷达图图表显示在首页

目标:封装一个echarts中的雷达图表显示在首页的绩效指数的位置

5.1 封装雷达图插件

首页中,还有一个绩效指数的位置需要放置一个雷达图的图表,我们可以采用百度的echarts进行封装

第一步, 安装echarts图表

npm i echarts

echarts是一个很大的包,里面包含了众多图形,假设我们只使用雷达图,可以做按需加载

第二步, 新建雷达图组件,src/views/dashboard/components/radar.vue

<template><!-- 雷达图  图表必须给高和宽度--><div ref="myDiv" class="radar-echart" />
</template><script>
// 完成加载过程
// var echarts = require('echarts')
var echarts = require('echarts/lib/echarts') // 引入echarts主模块
require('echarts/lib/chart/radar') // 引入雷达图
// 引入提示框和标题组件
require('echarts/lib/component/tooltip')
require('echarts/lib/component/title')export default {// 页面渲染完毕事件mounted() {const myChart = echarts.init(this.$refs.myDiv) // 得到图表实例myChart.setOption({title: {text: '基础雷达图'},tooltip: {},legend: {data: ['预算分配(Allocated Budget)', '实际开销(Actual Spending)']},radar: {// shape: 'circle',name: {textStyle: {color: '#fff',backgroundColor: '#999',borderRadius: 3,padding: [3, 5]}},// 每个区域的最高值indicator: [{ name: '工作效率', max: 100 },{ name: '考勤', max: 100 },{ name: '积极性', max: 100 },{ name: '帮助同事', max: 100 },{ name: '自主学习', max: 100 },{ name: '正确率', max: 100 }]},series: [{name: '预算 vs 开销(Budget vs spending)',type: 'radar',// areaStyle: {normal: {}},data: [{value: [10, 1, 100, 5, 100, 0],name: '张三'},{value: [50, 50, 50, 50, 50, 10],name: '李四'}]}]})}
}
</script><style>
.radar-echart {width: 600px;height: 400px;
}
</style>

注意:相关数据的缺失,所以这里我们进行的是模拟数据

  1. 在主页中引入使用
import Radar from './components/radar'
components: { Radar }

6.0 审批流程业务的基本介绍

6.1 提交一个离职审批

目标: 提交一个离职的审批,并完成业务流转

  1. 离职弹层
    <!-- 弹出层 --><el-dialog :visible="showDialog" title="离职申请" @close="btnCancel"><el-formref="ruleForm":model="ruleForm"status-iconlabel-width="110px":rules="rules"><!--离职表单--><el-form-item label="离职时间" prop="exceptTime"><el-date-picker v-model="ruleForm.exceptTime"type="datetime"value-format="yyyy-MM-dd HH:mm:ss"placeholder="选择日期时间"/></el-form-item><el-form-item label="离职原因" prop="reason"><el-inputv-model="ruleForm.reason"type="textarea":autosize="{ minRows: 3, maxRows: 8}"style="width: 70%;"placeholder="请输入内容"/></el-form-item></el-form><el-row slot="footer" type="flex" justify="center"><el-col :span="6"><el-button size="small" type="primary" @click="btnOK">确定</el-button><el-button size="small" @click="btnCancel">取消</el-button></el-col></el-row></el-dialog>
  1. 显示弹层
<el-button class="sideBtn" @click="showDialog = true">加班离职</el-button>
  1. 加班数据及校验
      showDialog: false,ruleForm: {exceptTime: '',reason: '',processKey: 'process_dimission', // 特定的审批processName: '离职'},rules: {exceptTime: [{ required: true, message: '离职时间不能为空' }],reason: [{ required: true, message: '离职原因不能为空' }]}
  1. 提交审批逻辑
import { startProcess } from '@/api/approvals'methods: {btnOK() {this.$refs.ruleForm.validate(async validate => {if (validate) {const data = { ...this.ruleForm, userId: this.userInfo.userId }await startProcess(data)this.$message.success('提交流程成功')this.btnCancel()}})},btnCancel() {this.showDialog = falsethis.$refs.ruleForm.resetFields()this.ruleForm = {exceptTime: '',reason: '',processKey: 'process_dimission', // 特定的审批processName: '离职'}}}
  1. 配置审批列表的导航
<el-button class="sideBtn" @click="$router.push('/users/approvals')">审批列表</el-button><el-button class="sideBtn" @click="$router.push('/users/info')">我的信息</el-button>
  1. 完成该流程的审批和流转

注意: 审批接口中的同意接口存在一定问题,可以测试 提交 /撤销 驳回等操作

7.0 枚举 Object.assign() 方法

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };const returnedTarget = Object.assign(target, source);console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
  1. 语法
    Object.assign(target, …sources)

  2. 参数
    target
    目标对象。
    sources
    源对象。

  3. 返回值
    目标对象。

7.2 描述

如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。

Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。该方法使用源对象的[[Get]]和目标对象的[[Set]],所以它会调用相关 getter 和 setter。因此,它分配属性,而不仅仅是复制或定义新的属性。如果合并源包含getter,这可能使其不适合将新属性合并到原型中。为了将属性定义(包括其可枚举性)复制到原型,应使用Object.getOwnPropertyDescriptor()和Object.defineProperty() 。

String类型和 Symbol 类型的属性都会被拷贝。

在出现错误的情况下,例如,如果属性不可写,会引发TypeError,如果在引发错误之前添加了任何属性,则可以更改target对象。

注意,Object.assign 不会在那些source对象值为 null 或 undefined 的时候抛出错误。

Vue 人资 实战篇九 其他模块集成和主页审批-图表-日历、echarts、 枚举的一个方法相关推荐

  1. Vue 人资 实战篇七 员工管理上 封装通用的组件、formatter属性、过滤器的使用、树形结构、建立公共导入的页面路由、excel的导入和导出、

    1.0 封装一个通用的工具栏 目标:封装一个通用的工具栏供大家使用 1.1 通用工具栏的组件结构 在后续的业务开发中,经常会用到一个类似下图的工具栏,作为公共组件,进行一下封装 组件 src/comp ...

  2. Vue 人资 实战篇八 权限设计 重点!!!路由访问权限,左侧导航栏显示等等,还有 mixin 混入方法

    1.0 权限设计-RBAC的权限设计思想 传统的权限设计是对每个人进行单独的权限设置,但这种方式已经不适合目前企业的高效管控权限的发展需求,因为每个人都要单独去设置权限 基于此,RBAC的权限模型就应 ...

  3. Vue项目实战之电商后台管理系统(二) 主页模块

    前言 目录 前言 一.主页布局 1.1 整体布局 1.2 头部区域布局 1.3 左侧菜单布局 1.3.1 静态布局 1.3.2 通过axios请求拦截器来进行权限验证 1.3.3 通过axios获取左 ...

  4. Vue实战篇二十九:模拟一个简易留言板

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  5. Vue实战篇三十三:实现新闻的浏览历史

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  6. Vue实战篇二十八:实现一个手机版的购物车

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  7. Vue实战篇三十一:实现一个改进版的头条新闻

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  8. Vue实战篇二十七:实现走马灯效果的商品轮播图

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

  9. Vue实战篇二十六:创建动态仪表盘

    系列文章目录 Vue基础篇一:编写第一个Vue程序 Vue基础篇二:Vue组件的核心概念 Vue基础篇三:Vue的计算属性与侦听器 Vue基础篇四:Vue的生命周期(秒杀案例实战) Vue基础篇五:V ...

最新文章

  1. OpenResty上各种测试用例实操(1)
  2. 7 Java Performance Metrics to Watch After a Major Release--转
  3. python无法启动此程序因为计算机中丢失_python报错:无法启动此程序,因为计算机中丢失...
  4. javascript网页特效_南通建网站哪些,网页设计维护
  5. MariaDB通过命令行的方式导出指定数据库和还原指定数据库
  6. 【Flink】Flink 运行 实时修改消费组offset
  7. oracle字段规则,Oracle的基本操作+Oracle字段类型(zz)
  8. wordpress发布文章错误:此响应不是合法的JSON响应
  9. 被 onnx.checker.check_model 检查出的常见错误
  10. 2022G3锅炉水处理上岗证题库及答案
  11. 戴尔Latitude5285笔记本触摸板失灵的原因
  12. 拍牌神器是怎样炼成的(二)--- 键鼠模拟之AutoIt
  13. python center() 函数
  14. 炒股软件周期分析怎么调,股票周期设置怎么设置
  15. 【暑期每日一题】洛谷 P6320 [COCI2006-2007#4] SIBICE
  16. yts1999 T2 容斥原理
  17. 4T磁盘只有2T可用,将mbr转为gpt安装操作系统。
  18. VMware vRealize Automation 8 Install
  19. Ray 部署及性能测试
  20. php图片镜像翻转,利用css动画属性rotate来实现镜像翻转

热门文章

  1. Allure使用手册
  2. 使用DNSCrypt解决DNS污染问题
  3. Android监控外接USB设备和获取USB等设备的详细信息
  4. FindWindowEx使用方法
  5. Delphi 在任务栏隐藏程序图标
  6. 最新采集下载QQ空间相册照片的方法
  7. 自然语言处理(Hanlp)
  8. 吉林省计算机二级vf试题,计算机二级vf考试试题
  9. FF800R12KE7HPSA1 IGBT 1200V 800A AG-62MM
  10. java per.get_Java ResultSetMetaData getPercision()方法与示例