项目问题参考答案

项目业务的功能:

  • 本系统主要包括7大板块,功能模块主要有门诊医生工作站,部门管理,医疗设备,医技科室,住院管理,药库药房,财务核算等模块,在门诊部中可以进行现场挂号,收费,退号等,当挂号收费完毕后医生可以进行问诊,开处方药,同时门诊医生可以开具检查项,只有开具检查项后医技医生才能进行此项检查,,也可以按照病人的情况来决定是否进行住院等,我主要负责部门管理,药库药房,系统管理的研发,参与项目v1.0到v2.0的迭代

1 完成部门管理模块(大致有药剂部门,诊疗部门、护理部门,后勤部门),

  • 我封装了Data-tree函数,通过递归将列表的数据进行转化为树结构,并搭配element-UI的Tree组件实现部门管理
let data = [
  {
    
     id: 0, pId: null, name: '生物' },
  {
    
     id: 1, pId: 0, name: '动物' },
  {
    
     id: 2, pId: 0, name: '植物' },
  {
    
     id: 3, pId: 0, name: '微生物' },
  {
    
     id: 4, pId: 1, name: '哺乳动物' },
  {
    
     id: 5, pId: 1, name: '卵生动物' },
  {
    
     id: 6, pId: 2, name: '种子植物' },
  {
    
     id: 7, pId: 2, name: '蕨类植物' },
]
  • 每个对象中id是唯一的,但不同对象的pId可以相同,可根据pId找到其父元素
export const arrayTwotree = (data, pid = '') => {
    
    
  
   // filter 过滤,查找子对象
  const tree = data.filter(item => item. === pid)
  tree.forEach(item => {
    
    
       //如果id与pid相同说明带有pid的对象是id这个对象的children 进行递归处理
    item.children = arrayTwotree(data, item.id)
  })
  return tree
}

2.在药品搜索模块,根据业务的需求,我封装了正则实现了模糊搜索,防抖工具函数,减少了请求,优化了项目

  • 详解防抖_.debounce(getUsername(),1000) , - 手写防抖
// 防抖的关键在于定时器的开始与清零
		function debounce(callback,delaytime){
    
    
			// 定义计时器
			let timer=null
			return function(){
    
    
				//如果定时器不是null 则需要重新计时
				if (timer!=null) {
    
    
					clearTimeout(timer)
					
				}
				//如果定时器还是空 ,则开始倒计时
				timer=setTimeout(()=>{
    
    
					callback&&callback()
				}, delaytime)

			}
		}
  • 节流_.throttle(getusername(),1000)
// 节流固定的时间进行触发
		inputEl.oninput = throttle(inputChange, 2000)
		// 封装节流  :关键在于: 节流阀 以及时间间隔
		//1 如果不触发函数则节流阀关闭状态
		// 当你触发这个函数时先把节流阀关闭 然后在默认的时间间隔中打开
		function throttle(callback, delaytime) {
    
    
			let state=true   //节流阀打开
			return function(){
    
    
				if (!state) {
    
      //当节流阀关闭,则直接退出该函数
					return;         //callback不执行
				}else{
    
    
					//如果节流阀打开先把节流阀关闭
					//然后设置时间间隔后在自动打开
					state = false       
					setTimeout(() => {
    
    
						callback && callback()
						state = true
					}, delaytime)
				}
			}

3. excel的导入导出

  • 导入:就是用fileReader将文件转化为ArrayBuffer,在调用xlsx第三方包read()方法转成workbook,由于fileReader是异步函数,所以使用promise.all进行处理,读取多个文件

导入详细解答

  1. 我封装了一个全局组件uploadExcel组件
  2. 在这个组件中,我结合element-ui组件库中的el-upload上传文件组件进行二次处理
<el-upload
  action=‘’
  accept=“xlsx/.xls”  // 指定文件类型
  on-change          //文件状态的改变
</el-upload>
  1. 当文件状态改变要进行导入时,调用fileReader方法把文件转换为二进制的数据(这里封装了一个Promise异步函数,只有resolve(成功)时才会进行文件的读取)
  2. 调用xlsx中内置的read方法 并指定类型进行文件数据的读取
  3. 利用xlsx中内置的sheet_to_json方法进行数据格式的转换(转成JSON数据格式)

导出函数,
1. 调用表格中的@selection-change事件会拿到选中的数据,
2. 把拿到的选中的数据进行中英文的map切换
3. 调用xlsx中内置的方法,把数据转换为sheet格式
4. 新建一个表格使用xlsx里面内置的utils。book_new()方法创建
5. 利用book_append_sheet方法向表格插入数据
6. 调用writeFile方法把数据写入当前文件
在这里插入图片描述

4. 登录模块

  • 包括登录前的数据收集和校验,
    1. 点击登录按钮通过dispatch调用vuex里面的actions发送aixos请求给服务器,后台返回响应状态码判断是否成功,失败则提示用户,
    1. 成功则将返回数据中的token持久化并同步到 Vuex;
    1. 对后续需要携带 Token 的接口在请求拦截器处进行统一处理;对 Token 过期的情况配合后端我做了无感刷新处理机制,提升用户使用网站的体验;结合路由导航守卫对登录后才能访问的内页实现了界面访问控制的功能

5 无感刷新的实现

  • 弄两个token,一个负责鉴权的 token:access_token,一个负责刷新token:refresh_token,
  • 每次请求的时候都带上这两个token,再由后端拦截器判断,先判断鉴权token是否有效,
  • 如果有效就访问,无效就判断刷新token是否有效,有效就返回指定状态码,
  • 然后让我根据状态码调用刷新token的接口,如果刷新token失效,就提示重新
    在这里插入图片描述

6权限管理

  • 首先会有一个超级管理员,进行角色权限的分配,
  • 当用户登录跳转首页时,在路由前置守卫中,判断是否携带token,并调用dispatch在actions中发送用户信息请求了并保存在vuex中,
  • 获取vuex中的用户权限信息的数组,筛选路由配置中name标识,
  • 是否在当前用户信息数组中,然后通过add-router动态添加路由,显示能访问的菜单页面

7按钮权限

  • 解决方案一:

    • 1.定义一个全局方法,配合v-if实现
    • 思路:在用户登录成功后,获取用户的按钮权限(数组格式),存储到store中,然后在工具类中定义一个公共函数hasIsEdit,在按钮中调用hasIsEdit()函数,把传入的关键字和store的按钮权限进行对比,看看是否存在,如果存在就显示,不存在就隐藏
  • 解决方案二

    ①定义一个全局自定义指令:按钮级别的权限只需要在main.js里封装一个全局的指令或方法,这个方法只做一件事情,接收后端返回的标识,也就是该用户所拥有按钮级别权限的数组。
    ②拿到标识后,内部判断一下这个标识在不在该数组里面,不在就把该按钮的样式设置隐藏。
    ③在需要做按钮权限的地方调用:值为和后端约定的权限标识。

// 控制页面中按钮的级别
Vue.directive('allow', {
    
       // binding是个形参,接收调用自定义指令的标识进行判断
  inserted: function(el, binding) {
    
    
    // 1. 首先需要获取到vuex中用户按钮级别的权限信息
    console.log(binding, 'bindingbinding')
    const points = store.state.user.userInfo.roles.points
    // 2. 根据使用指令传过来的权限标识, 判断用户拥有按钮级别的权限
    if (!points.includes(binding.value)) {
    
    
      el.style.display = 'none'
    }
  }
})
<button v-allow="'import_excel'">删除用户信息</button>
//import_excel 是和后端约定的按钮权限标识

8 模块拆分

在这里插入图片描述

  1. 模块拆分主要分为 production:生产环境
  2. development:开发环境
  3. 公共资源
3.	公共资源  主要放置loader与resolve: {
    
    
4.	        extensions: ['.js', '.vue', '.json'],
5.	        alias: {
    
    
6.	            'vue$': 'vue/dist/vue.esm.js',
7.	            '@': path.join(__dirname, '../src')
8.	        }
9.	    },
  1. 开发环境:主要放置deverserve 跨域的代理
  2. 生产环境:主要放置css压缩,JS压缩
// css压缩
optimize-css-assets-webpack-plugin
 //dist压缩包
 "zip-webpack-plugin": "^4.0.1"
//生产环境 copy静态资源
 "copy-webpack-plugin": "^11.0.0"

具体参考

9. 后端返回的二进行文件流数据如何处理

  1. 先创建将一个a交钱

10 el-table渲染大量数据造成卡顿问题

1.解决方案一:利用pl-table解决el-tree与el-table的数据量过大,(长列表的方式)
2.使用u-table解决

猜你喜欢

转载自blog.csdn.net/weixin_46104934/article/details/127988836