页面预览就诊人管理就诊人列表
添加就诊人
查看就诊人
![image-20230225060710
管理员系统用户管理
前面我们完成了用户登录、用户认证与就诊人管理,现在我们需要把这些信息在我们的平台管理系统中进行统一管理
用户列表用户详情
第01章-token刷新
简单的设置redis和cookie的过期时间,会导致用户在操作的过程中掉线,为了解决这个问题,我们可以使用token续期的方案,具体的做法是生成一个刷新token。
1、存储token
设置token与refreshToken
,都包含用户信息(userId、name、headimgurl),可以一样可以不一样,refreshToken比token时间更长,如token30分钟,refreshToken60分钟
在ApiWxController的callback方法的return "redirect:"
前面,将之前的生成token和存储token的相关代码封装到saveToken方法中。
将如下代码进行封装:
封装成如下代码:
@Resourceprivate AuthContextHolder authContextHolder;
UserVo userVo = new UserVo();userVo.setName(name);userVo.setUserId(userInfo.getId());userVo.setHeadimgurl(userInfo.getHeadImgUrl());authContextHolder.saveToken(userVo, response);return "redirect:" + constantProperties.getSytBaseUrl();
service-util中引入依赖
com.atguigu model 1.0
在AuthContextHolder中添加如下方法:
/** * 将token和refreshToken保存在redis和cookie中的通用方法 * @param userVo * @param response */public void saveToken(UserVo userVo, HttpServletResponse response) { int redisMaxTime = 30; //生成token/refreshToken String token = getToken(); String refreshToken = getToken(); //将生成token/refreshToken存入redis:token做键,userVo做值 redisTemplate.opsForValue()//30分钟 .set("user:token:" + token, userVo, redisMaxTime, TimeUnit.MINUTES); redisTemplate.opsForValue()//60分钟 .set("user:refreshToken:" + refreshToken, userVo, redisMaxTime * 2, TimeUnit.MINUTES); //将token、refreshToken和name存入cookie int cookieMaxTime = 60 * 30;//30分钟 CookieUtils.setCookie(response, "token", token, cookieMaxTime); CookieUtils.setCookie(response, "refreshToken", refreshToken, cookieMaxTime * 2); CookieUtils.setCookie(response, "name", URLEncoder.encode(userVo.getName()), cookieMaxTime * 2); CookieUtils.setCookie(response, "headimgurl", URLEncoder.encode(userVo.getHeadimgurl()), cookieMaxTime * 2);}
private String getToken(){ return UUID.randomUUID().toString().replaceAll("-", "");}
3、续期token
修改checkAuth方法,当token不存在时,续期token
/** * 检查授权状态并续期 * @param request * @return */public Long checkAuth(HttpServletRequest request, HttpServletResponse response){ //从http请求头中获取token String token = request.getHeader("token"); if(StringUtils.isEmpty(token)) { //throw new GuiguException(ResultCodeEnum.LOGIN_AUTH); return refreshToken(request, response);//刷新token } Object userVoObj = redisTemplate.opsForValue().get("user:token:" + token); if(userVoObj == null){ //throw new GuiguException(ResultCodeEnum.LOGIN_AUTH); return refreshToken(request, response);//刷新token } UserVo userVo = (UserVo)userVoObj; return userVo.getUserId();}
/** * 刷新token * @param request * @param response * @return */public Long refreshToken(HttpServletRequest request, HttpServletResponse response) { //从cookie中获取刷新token String refreshToken = CookieUtils.getCookie(request, "refreshToken"); //从redis中根据刷新token获取用户信息 Object userVoObj = redisTemplate.opsForValue().get("user:refreshToken:" + refreshToken); if(userVoObj == null) { //LOGIN_AURH(214, "登录过期"), throw new GuiguException(ResultCodeEnum.LOGIN_TIMEOUT);//登录过期 } UserVo userVo = (UserVo) userVoObj; saveToken(userVo, response); return userVo.getUserId();}
4、修改checkAuth方法的调用
FrontUserInfoController和FrontFileController中的方法,添加response参数
5、cookie跨域
跨域ajax访问时,session_id不会被存储,cookie不会被传递到后端,因此需要解决cookie跨域存储的问题
解决方案:
(1)网关配置文件CorsConfig中添加如下设置:
config.setAllowCredentials(true); //避免跨域访问时session_id每次不一致
(2)前端axios初始化文件request.js添加如下设置:
withCredentials: true //避免跨域访问时session_id每次不一致
6、前端request.js拦截处理
如果接口返回214状态(登录超时),说明用户超时未操作,直接退出。
// http response 拦截器service.interceptors.response.use(response => {//如果响应码是214,则需要登录超时if (response.data.code === 214) {// to re-loginMessageBox.confirm('登录超时, 请重新登录', '确认退出', {confirmButtonText: '重新登录',cancelButtonText: '回到首页',type: 'warning'}).then(() => {window.location.href = process.env.BASE_API + '/front/user/wx/login'}).catch(()=>{window.location.href = '/'})}else if (response.data.code !== 200) {Message({message: response.data.message,type: 'error',duration: 5 * 1000})return Promise.reject(response.data)} else {return response.data}},error => {return Promise.reject(error.response)})
7、myheader.vue
myheader.vue中showInfo方法的修改,保证token过期后,用户名信息依然显示
showInfo() { let refreshToken = cookie.get('refreshToken') if (refreshToken) { this.name = cookie.get('name') this.headimgurl = cookie.get('headimgurl') }},
myheader.vue中退出登录方法的修改,需要清空refreshToken
cookie.set('name', '', {domain: 'localhost'})cookie.set('token', '', {domain: 'localhost'})cookie.set('refreshToken', '', {domain: 'localhost'}) //清空refreshTokencookie.set('headimgurl', '', {domain: 'localhost'})
补充:由于我们解决了cookie的ajax传递跨域问题,因此之前通过header传输的token其实可以不必要了,我们可以直接在后端从cookie中获取token的值,如下:
String token = request.getHeader("token");//以上可以替换为如下:String token = CookieUtils.getCookie(request, "token");
第02章-就诊人管理1、后端接口1.1、添加就诊人
FrontPatientController:
package com.atguigu.syt.user.controller.front;@Api(tags = "就诊人管理")@RestController@RequestMapping("/front/user/patient")public class FrontPatientController { @Resource private PatientService patientService; @Resource private AuthContextHolder authContextHolder; @ApiOperation("添加就诊人") @ApiImplicitParam(name = "patient",value = "就诊人对象", required = true) @PostMapping("/auth/save") public Result savePatient(@RequestBody Patient patient, HttpServletRequest request, HttpServletResponse response) { Long userId = authContextHolder.checkAuth(request, response); patient.setUserId(userId); patientService.save(patient); return Result.ok().message("保存成功"); }}
1.2、修改
FrontPatientController:
@ApiOperation("修改就诊人")@ApiImplicitParam(name = "patient",value = "就诊人对象", required = true)@PutMapping("/auth/update")public Result updatePatient(@RequestBody Patient patient, HttpServletRequest request, HttpServletResponse response) { authContextHolder.checkAuth(request, response); patientService.updateById(patient); return Result.ok().message("修改成功");}
1.3、根据id获取就诊人
FrontPatientController:
@ApiOperation("根据id获取就诊人信息")@ApiImplicitParam(name = "id",value = "就诊人id", required = true)@GetMapping("/auth/get/{id}")public Result getPatient(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) { Long userId = authContextHolder.checkAuth(request, response); //加上userId参数,只可以获取自己名下的就诊人信息 Patient patient = patientService.getPatientById(id, userId); return Result.ok(patient);}
接口:PatientService
/** * 根据id获取本人名下的就诊人信息 * @param id * @param userId * @return */Patient getPatientById(Long id, Long userId);
实现:PatientServiceImpl
@Overridepublic Patient getPatientById(Long id, Long userId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(Patient::getUserId, userId).eq(Patient::getId, id); Patient patient = baseMapper.selectOne(queryWrapper); //封装数据 return this.packPatient(patient);}
辅助方法
@Resourceprivate DictFeignClient dictFeignClient;@Resourceprivate RegionFeignClient regionFeignClient;
/** * 封装Patient对象里面其他参数 * @param patient * @return */private Patient packPatient(Patient patient) { String certificatesTypeString = dictFeignClient.getName(DictTypeEnum.CERTIFICATES_TYPE.getDictTypeId(),patient.getCertificatesType()); String contactsCertificatesTypeString = dictFeignClient.getName( DictTypeEnum.CERTIFICATES_TYPE.getDictTypeId(),patient.getContactsCertificatesType()); String provinceString = regionFeignClient.getName(patient.getProvinceCode()); String cityString = regionFeignClient.getName(patient.getCityCode()); String districtString = regionFeignClient.getName(patient.getDistrictCode()); patient.getParam().put("certificatesTypeString", certificatesTypeString); patient.getParam().put("contactsCertificatesTypeString", contactsCertificatesTypeString); patient.getParam().put("provinceString", provinceString); patient.getParam().put("cityString", cityString); patient.getParam().put("districtString", districtString); patient.getParam().put("fullAddress", provinceString + cityString + districtString + patient.getAddress()); return patient;}
1.4、获取就诊人列表
FrontPatientController
@ApiOperation("获取就诊人列表")@GetMapping("/auth/findAll")public Result<List> findAll(HttpServletRequest request, HttpServletResponse response) { Long userId = authContextHolder.checkAuth(request, response); List list = patientService.findByUserId(userId); return Result.ok(list);}
接口:PatientService
/** * 根据userId获取就诊人列表 * @param userId * @return */List findByUserId(Long userId);
实现:PatientServiceImpl
@Overridepublic List findByUserId(Long userId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(Patient::getUserId, userId); List patientList = baseMapper.selectList(queryWrapper); patientList.forEach(patient -> { patient.getParam().put("expenseMethod", patient.getIsInsure()==0?"自费":"医保"); }); return patientList;}
1.5、删除就诊人
FrontPatientController:
@ApiOperation("删除就诊人")@DeleteMapping("/auth/remove/{id}")public Result removePatient(@PathVariable Long id, HttpServletRequest request, HttpServletResponse response) { Long userId = authContextHolder.checkAuth(request, response); //加上userId参数,只可以删除自己名下的就诊人信息 patientService.removeById(id, userId); return Result.ok();}
接口:PatientService
/** * 根据id删除自己名下的就诊人信息 * @param id * @param userId */void removeById(Long id, Long userId);
实现:PatientServiceImpl
@Overridepublic void removeById(Long id, Long userId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); queryWrapper.eq(Patient::getUserId, userId).eq(Patient::getId, id); baseMapper.delete(queryWrapper);}
2、前端整合2.1、api
创建api/patient.js
import request from '~/utils/request'export default { save(patient) { return request({ url: `/front/user/patient/auth/save`, method: 'post', data: patient }) }, updateById(patient) { return request({ url: `/front/user/patient/auth/update`, method: 'put', data: patient }) }, getById(id) { return request({ url: `/front/user/patient/auth/get/${id}`, method: 'get' }) }, findList() { return request({ url: `/front/user/patient/auth/findAll`, method: `get` }) }, removeById(id) { return request({ url: `/front/user/patient/auth/remove/${id}`, method: 'delete' }) }}
2.2、页面渲染
资料:资料>就诊人管理>
就诊人列表:pages/patient/index.vue
就诊人添加与修改 :pages/patient/add.vue
就诊人详情与删除:pages/patient/show.vue
第03章-管理系统用户管理(作业)1、后端接口1.1、用户列表
AdminUserInfoController:
package com.atguigu.syt.user.controller.admin;@Api(tags = "用户管理接口")@RestController@RequestMapping("/admin/user/userInfo")public class AdminUserInfoController { @Resource private UserInfoService userInfoService; @ApiOperation("分页条件查询") @ApiImplicitParams({ @ApiImplicitParam(name = "page",value = "页码",required = true), @ApiImplicitParam(name = "limit",value = "每页记录数",required = true), @ApiImplicitParam(name = "userInfoQueryVo",value = "查询对象",required = false) }) @GetMapping("/{page}/{limit}") public Result<IPage> list( @PathVariable Long page, @PathVariable Long limit, UserInfoQueryVo userInfoQueryVo ) { Page pageParam = new Page(page,limit); IPage pageModel = userInfoService.selectPage(pageParam, userInfoQueryVo); return Result.ok(pageModel); }}
Service接口:UserInfoService
/** * 查询用户分页列表 * @param pageParam * @param userInfoQueryVo * @return */IPage selectPage(Page pageParam, UserInfoQueryVo userInfoQueryVo);
Service实现:UserInfoServiceImpl
@Overridepublic IPage selectPage(Page pageParam, UserInfoQueryVo userInfoQueryVo) { //UserInfoQueryVo获取条件值 String keyword = userInfoQueryVo.getKeyword(); //用户名称 String createTimeBegin = userInfoQueryVo.getCreateTimeBegin(); //开始时间 String createTimeEnd = userInfoQueryVo.getCreateTimeEnd(); //结束时间 //对条件值进行非空判断 LambdaQueryWrapper wrapper = new LambdaQueryWrapper(); wrapper.and(!StringUtils.isEmpty(keyword), i -> i.like(UserInfo::getName, keyword).or().like(UserInfo::getPhone, keyword)) .ge(!StringUtils.isEmpty(createTimeBegin), UserInfo::getCreateTime, createTimeBegin) .le(!StringUtils.isEmpty(createTimeEnd), UserInfo::getCreateTime, createTimeEnd); //调用mapper的方法 IPage pages = baseMapper.selectPage(pageParam, wrapper); //编号变成对应值封装 pages.getRecords().forEach(this::packUserInfoForList); return pages;}
辅助方法:
/** * 封装用户状态、认证状态、证件类型信息 * @param userInfo * @return */private UserInfo packUserInfoForList(UserInfo userInfo) { //判断用户是否已经提交实名认证 if(userInfo.getAuthStatus().intValue() != AuthStatusEnum.NO_AUTH.getStatus().intValue()){ String certificatesTypeString = dictFeignClient.getName( DictTypeEnum.CERTIFICATES_TYPE.getDictTypeId(), userInfo.getCertificatesType() ); userInfo.getParam().put("certificatesTypeString", certificatesTypeString); } userInfo.getParam().put("authStatusString", AuthStatusEnum.getStatusNameByStatus(userInfo.getAuthStatus())); userInfo.getParam().put("statusString", UserStatusEnum.getStatusNameByStatus(userInfo.getStatus())); return userInfo;}
1.2、锁定和解锁
Controller:在AdminUserInfoController中添加方法
@ApiOperation("锁定和解锁")@ApiImplicitParams({ @ApiImplicitParam(name = "userId",value = "用户id",required = true), @ApiImplicitParam(name = "status",value = "用户状态",required = true)})@PutMapping("lock/{userId}/{status}")public Result lock( @PathVariable("userId") Long userId, @PathVariable("status") Integer status){ boolean result = userInfoService.lock(userId, status); if(result){ return Result.ok().message("设置成功"); }else{ return Result.ok().message("设置失败"); }}
Service接口:UserInfoService
/** * 锁定和解锁用户 * @param userId * @param status * @return */boolean lock(Long userId, Integer status);
Service实现:UserInfoServiceImpl
@Overridepublic boolean lock(Long userId, Integer status) { if(status == 0 || status == 1){ UserInfo userInfo = new UserInfo(); userInfo.setId(userId); userInfo.setStatus(status); return this.updateById(userInfo); } return false;}
1.3、用户详情
Controller:在AdminUserInfoController中添加方法
@ApiOperation("用户详情")@ApiImplicitParam(name = "userId",value = "用户id",required = true)@GetMapping("show/{userId}")public Result<Map> show(@PathVariable Long userId) { return Result.ok(userInfoService.show(userId));}
Service接口:UserInfoService
/** * 根据用户id获取用户详情 * @param userId * @return */Map show(Long userId);
Service实现:UserInfoServiceImpl
@Resourceprivate PatientService patientService;
@Overridepublic Map show(Long userId) { Map map = new HashMap(); //根据userid查询用户信息 UserInfo userInfo = this.packUserInfo(baseMapper.selectById(userId)); map.put("userInfo",userInfo); //根据userid查询就诊人信息 List patientList = patientService.findByUserId(userId); map.put("patientList",patientList); return map;}
1.4、用户认证审批
Controller:在AdminUserInfoController中添加方法
@ApiOperation("认证审批")@ApiImplicitParams({ @ApiImplicitParam(name = "userId",value = "用户id",required = true), @ApiImplicitParam(name = "authStatus",value = "用户认证审批状态",required = true)})@PutMapping("approval/{userId}/{authStatus}")public Result approval(@PathVariable Long userId, @PathVariable Integer authStatus) { boolean result = userInfoService.approval(userId,authStatus); if(result){ return Result.ok().message("审批成功"); }else{ return Result.ok().message("审批失败"); }}
Service接口:UserInfoService
/** * 审核用户 * @param userId * @param authStatus * @return */boolean approval(Long userId, Integer authStatus);
Service实现:UserInfoServiceImpl
/** * 认证审批 2通过 -1不通过 * @param userId * @param authStatus * @return */@Overridepublic boolean approval(Long userId, Integer authStatus) { if(authStatus == AuthStatusEnum.AUTH_SUCCESS.getStatus() || authStatus == AuthStatusEnum.AUTH_FAIL.getStatus()){ UserInfo userInfo = new UserInfo(); userInfo.setId(userId); userInfo.setAuthStatus(authStatus); return this.updateById(userInfo); } return false;}
2、前端整合2.1、页面
在后台管理系统前端项目中添加如下页面,资料:资料>用户管理
用户列表:src/views/syt/userInfo/list.vue
用户详情,详情页面展示用户信息、用户就诊人信息:src/views/syt/userInfo/show.vue
2.2、路由
静态路由:
{ path: '/userInfo', component: Layout, redirect: '/userInfo/list', name: 'userInfo', meta: { title: '用户管理', icon: 'user' }, alwaysShow: true, children: [ { path: 'list', name: 'userInfoList', component: () => import('@/views/syt/userInfo/list'), meta: { title: '用户列表', icon: 'el-icon-s-unfold' } }, { path: 'show/:id', name: 'userInfoShow', component: () => import('@/views/syt/userInfo/show'), meta: { title: '查看用户' }, hidden: true } ] },
动态路由:
用户管理:
用户列表:
查看用户:
2.3、api
创建src/api/syt/userInfo.js
import request from '@/utils/request'const apiName = '/admin/user/userInfo'export default { //用户列表 getPageList(page, limit, searchObj) { return request({ url: `${apiName}/${page}/${limit}`, method: 'get', params: searchObj }) }, //锁定与解锁 lock(id, status) { return request({ url: `${apiName}/lock/${id}/${status}`, method: 'put' }) }, //用户详情 show(id) { return request({ url: `${apiName}/show/${id}`, method: 'get' }) }, //认证审批 approval(id, authStatus) { return request({ url: `${apiName}/approval/${id}/${authStatus}`, method: 'put' }) }}
源码:https://gitee.com/dengyaojava/guigu-syt-parent
本文来自博客园,作者:自律即自由-,转载请注明原文链接:https://www.cnblogs.com/deyo/p/17487118.html