人力资源后台管理系统_hrsaas
1.项目介绍:
hrsaas是一款对公司员工管理的后台管理系统,主要实现功能:公司组织架构的增删改查,公司角色的增删改查以及公司信息内容展示,员工信息的查阅,员工在公司的工作状态,是否转正,离职,调岗,担任的职位等等
2.项目主要模块:登录,主页,组织架构,公司设置,员工管理,权限管理
3.该项目的亮点:
权限管理:不同的角色登录进入到首页,看到的菜单应该是不一样的,比如系统管理员,可以看到所有的模块,而普通员工只能看到首页,考勤,工资,社保这四个模块
4.开发项目所用到技术:
1)基于vue-element-template 进行项目的二次开发和功能的扩展,因为这个基本模块中包含了基本的登录/权限架子/主页布局,可以提高开发效率,节省开发时间
2)vuex:项目采用了模块化形式进行管理共享状态,方便维护
3) git:远程仓库进行代码托管
4) axios:项目中采用API 的单独模块封装,统一管理,对axios二次封装进行开发,此项目封装成的是request模块
5) vue-router: 页面切换,控制用户登录权限控制,路由全局前置守卫,路由全局后置守卫
6 ) scss :项目使用了 scss 作为css 的扩展语言
7)svg-sprites:svg 精灵图
8 ) 解决开发环境跨域:只需要在vue-cli脚手架环境中起一个代理服务器,此项目真正部署上线时的跨域是后台配置了cors解决的
5.我所负责的有登录,组织架构,公司设置,员工管理
登录模块:
实现功能:用户输入用户名和密码,如果用户名和密码都正确,点击登录就跳转到首页,密码或用户名不正确就给用户相对应的提示:如 用户名错误,请重新输入,并且不进行跳转到首页
开发过程:
1.准备登录页面的基础布局
涉及到的知识点:在css样式中,如果想用@ 别名时,需要在@前面加一个~,否则不识别此别名;@ 是在vue.config.js中设置的路径别名,指定src根目录,目的是方便找指定的文件,需要引一个jsconfig.js 文件才支持
2.登录表单验证
涉及到的知识点:基本模块中,虽然做了一些校验,但是不完全符合此项目的 校验规则,所以进行了校验的优化:1)字段名对应:基础模板采用的是username
的字段,但是实际接口中采用的是mobile
的字段,为了更方便的写代码,所以我将username
改成mobile
这里除了字段名,还有项目的规则校验名称,以及prop名称 2)英文提示变成中文 :基础模板中都是placeHolder占位符是英文,要变成中文,登录按钮文字同样需要换成中文 3)校验手机号和校验密码:基础模板中,已经做了校验,我又根据需求针对代码进行一些优化新规则:手机号必填,并且进行格式校验,密码必填,长度6-16位之间,运用到了element-ui的自定义校验,需要配置四个必须的属性:在el-form 标签里面配置 :model="loginForm", :rules="loginRules" ,给el-form-item 标签上面配置 prop="mobile", 给el-input 标签配置 v-model="loginForm.mobile" (其中:loginForm 在data中提供的数据,loginRules是在data中提供的校验规则集合,是个对象里面配置每一个字段的校验规则,mobile表示loginRules里面对应的mobile字段校验规则名,v-model表示 绑定loginForm 里面的 mobile 数据)
3.封装请求登录的接口:reqLogin()
涉及到开发环境跨域:配置一个代理服务器 vue.config.js 配置文件中
devServer: { // 代理配置 proxy: { // 这里的api 表示如果我们的请求地址有/api的时候,就出触发代理机制 '/api': { target: '我们要代理请求的地址', }, } }
在.env.development 系统环境变量里面配置VUE_APP_BASE_API = '/api' ('/api' 是 'http://localhost:8888/api'的简写)
在request.js 文件 里面的axios实例里面配置 根路径 baseULR=process.env.VUE_APP_BASE_API (process.env. 是调用系统环境变量的语法)
4.在登录按钮上绑定点击事件,在事件处理函数中,进行表单验证判断,如果没有通过校验,直接return ,如果通过校验,显示loading ,发起登录的请求,请求成功,需要对返回回来的数据进行处理,处理完,结束loading,然后跳转到首页,登录功能完成.
数据处理涉及到:
1.vuex 管理token :把token 存在vuex 中,方便组件进行获取,如果想要操作token 必须提交mutation 进行修改,在存的时候我并没有直接把token 存在 store 的index.js文件里面,而是进行分模块存储,把token 存在了 user 模块 的state 里面,并配置namespaced:true 变成一个user 私有的仓库,把user 这个模块挂在 store 里的modules 里面,把设置 修改state里面token 的方法,放到mutations 里面, 因为只有提交mutation 才能修改到state 里面的数据,把登录发请求的接口封装成reqLogin,然后在 actions 里面 发请求,然后从返回的数据中解构出 token ,然后提交mutations 里面封装好的setToken 这个mutation , 把请求回来最新的token 值存在state中,页面中就不用发起登录请求了,可以直接通过辅助函数mapAction,调用到封装好的action ,setToken 就可以实现发请求校验密码跟手机号,成功直接进行跳转首页操作即可
store/modules/user.js
代码:const state={token: " "} const mutations={getToken(state,newtoken){ state.token=newtoken}} const actions={ async setToken(context){ const res= await reqLogin() newToken=res.token context.commit("setToken",newToken)}} const getters={}
export default {namespaced:true,state,mutations,actions,getters}
代码优化:为了以后更好的让其他模块和组件更好的获取到token 数据,我就在 store 文件下新建一个getters文件,在getters.js 文件中把token 添加成了公用的getters,然后导出,便于将来访问,没有直接写在 store 里面的getters 中是为方便维护,避免store/index 中的代码过于混乱
知识点:vuex 中的核心模块 state 用来存储数据,保证数据是响应式的,getters 依赖于state 衍生出来的数据 mutations 用于修改state中的数据,只支持同步,actions 一般用于封装一些异步操作,提交mutation修改state中的数据,
利用vuex 进行存取可以获取到最新的数据但是,vuex 有一个特点,一刷新页面状态就会丢失,所以想要持久化,所以我还在cookie中存了一份
2.cookie 存储token :element-ui 在utils/auth.js中,已经提供好了 获取token ,设置token ,删除token 的方法,分别为setToken(),getToken(),removeToken(),可以直接使用,只需要将存储的key 放置成特定值即可:
代码优化:
1)把auth.js里面三个方法导入到store/modules/user.js中一进来先从缓存cookie中获取 token 把store/modules/user.js 中的token 设置为getToken() 获取token 字符串,在mutations 里面设置token 的同时,同步到本地cookies中 setToken(newToken)
2)action 是异步的,可以使用async 和await 进行请求的优化代码
3.axios 的响应拦截器处理响应:在请求完成之后,如果成功就进行页面跳转,但是失败也进行页面跳转,因为后台只是将 success 字段标记为false 了,成功就把 success 字段标记为 true,所以我决定将错误进行统一处理,一旦发现success为false,就在响应器中抛出错误,不让走.then 走.catch
1)处理axios 默认的一层包裹 2)统一对错误响应进行处理,提示用户错误信息,使用到promise
代码优化:
在响应拦截器里面处理:
instance.interceptors.response.use(function(response){
const res=response.data
const {message,success}=res
if(!success){ Message.error(message) //提示错误信息并返回一个错误的promise对象 return Promise.reject(new Errow(message))} return res},function(error){ Message.error(error.message) //提示错误信息return Promise.reject(error)})
涉及到的知识点:Promise 汉语意思是承若,一般承诺的都是将来的事情,有成功,有失败,所以promise 有三个状态:pending ,fulfilled,rejected,pending 是等待的状态,fulfilled是成功的状态,rejected 是失败的状态,promise 的状态一旦改变就不能修改,称为状态凝固,promise的语法是 new 一个Promise 对象,然后使用他的.then.catch方法
new Promise((reslove,reject)=>{
promise 内部可以封装一个异步操作
resolve 在成功的时候调用的函数,将promise的状态从pending 改成了 fulfiled
reject 在失败的时候调用的函数,将promise 的状态从 pending 改成 rejected
})
resolve()走的是.then(),rejecte() 走的是.catch()
这个项目里面还用到了 .finally(){ 不管成功还是失败都会执行,就是结束loading 的时候使用}
promise还有.race() 和.all()的静态方法,.race() 是竞赛原则,里面的异步操作是一个数组,只有其中有一个完成了就走.then 。 .all()是等待原则,只有当数组里面的所以异步操作都完成之后,才会走.then
Promise 是为了解决回调地狱的问题而生的,支持链式编程,但是当异步操作很多时,链式会很长,不方便维护,就出现了 async 和await ,他们是优化了promise 但不是为了替代promise ,回调地狱是根据需求,就是当需要等一个异步操作完成之后再去做某些事是,就需要函数嵌套,这样一层一层嵌套,维护起来有种在地狱的感觉,就被称为了回调地狱,而现在解决想要在完成异步之后做某些事可以用promise
解决方案:反向代理,token处理,请求模块封装,异步编程
项目中收获的经验:对vuex的调试工具使用更熟悉了